stdoutバッファを削除するには、「unbuffer」または「stdbuf」を使用しますか?

stdoutバッファを削除するには、「unbuffer」または「stdbuf」を使用しますか?

unbuffer(1) と stdbuf(1) に違いはありますか?私が知っている限り、unbufferは最初にlibc関数set(X)bufを呼び出してからそのままにする以上の機能を実行します。

答え1

彼らはまったく異なる方法で動作します。

unbuffer プログラムは、指定されたコマンドを実行するために使用します。 Expectは子プロセスのstdoutに接続するために擬似ttyを生成するので、子プロセスはブロックバッファリングの代わりにラインバッファリングを使用する必要があると思うように欺くことができます。一部のプログラムはisatty(stdout)がtrueのときに動作を変更しますが、他のプログラムはそうではなく、どのプログラムが変更され、どのプログラムが変更されないかを知ることは困難です。

動的にロードされたバイナリの場合、stdbufプログラムはlibstdbufをlibcの前に配置しようとします。そのうち、libstdbuf は libc stdio 呼び出しの基本的なバッファリング戦略を上書きします。

私はこれを見つけました

 apt-get source expect coreutils

そして、各プログラムの関連ソースコードを読んでください。

答え2

長い話を短く

これ以前に許可された回答それでも正確です。私の経験から見ると、最大の違いはバッファリング解除-p使いやすく、パイプから標準入力をバッファリングするためのスイッチ()のみを提供します。バッファキャンセルいいえ。

具体的なユースケースはさまざまですが、次の一般的なアドバイスをしたいと思います。

  1. 使用バッファリングされていないstdinをバッファリングする必要があり、stdinバッファリングの制限がわかっている場合、つまりパイプが早く終了するか、EOFで早く終了すると停止します。
  2. 使用標準バッファ入力、出力、およびエラーI / Oストリームのバッファリングに別々の制御が必要で、標準入力をバッファリングする必要がない場合。

CoreutilsのStdbuf

これ標準バッファGNUのいくつかのユーティリティ、入力、出力、およびエラーストリームに別々のフラグを提供します。マニュアルページに以下の事項が記載されている点は注目に値する。

  1. 独自にバッファを調整するteeなどのコマンドは影響を受けません。
  2. I/O ストリームを使用しないフィルタは影響を受けません。
  3. ラインバッファリングは標準入力には影響しません。

だから一般的に言えば、標準バッファより多くのコントロールを提供バッファリング解除しかし、いくつかの注意事項があります。man 1 stdbuf(またはman 1 gstdbuf一部のシステムでは)次のように言います。

注:COMMANDが標準ストリーム(「tee」など)のバッファリングを調整する場合、「stdbuf」への対応する変更は上書きされます。また、一部のフィルタ(「dd」や「cat」など)はI / Oストリームを使用しないため、「stdbuf」設定の影響を受けません。

バグ
GLIBC プラットフォームでフルバッファモードを使用してもバッファサイズを指定すると、未定義の動作が発生します。

Expectでバッファリングされない

これバッファリングされていない標準の一つであるコマンドノブが少ないコマンドラインのサンプルツールです。これはあなたに良いかもしれないし、そうではないかもしれません。個人的に私は単純なものを好まない限り必要追加のハンドル。一方、標準バッファ標準入力には適用されません。バッファリングされていないはい、このオプションは可能です-p

通常、unbufferはstdinから読み込まれません。これは、場合によってはアンバッファの使用を簡素化する。パイプラインでバッファ解除を有効にするには、-pフラグを使用します。

ただし、この動作には注意事項とその理由に関する追加の説明が含まれていますman 1 unbuffered。次の内容をお読みください。

unbuffer -p は、unbuffer への入力を提供するプロセスが終了すると正しく動作しない可能性があります。考慮する:

             プロセス1 |バッファリングキャンセル-pプロセス3 |

process1 が終了すると、process2 がまだ完了していない可能性があります。 unbufferはprocess2をどれだけ待つべきかわからず、process2は例えばフィルタの場合は完了しないかもしれません。便宜上、アンバッファは、入力またはプロセス2でEOFに遭遇すると簡単に終了します。

この場合、バッファリングされていないExpectを直接使用するか、他のさまざまな回避策を使用してパイプラインを手動で調整することをお勧めします。

関連情報