RSS ジュリア・エヴァンス
フォロー
「パイプが時々「詰まる」理由:バッファリング」
バッファリングは、ターミナルプログラムでパフォーマンスを向上させるために一般的に行われます。パイプにデータが遅く追加される場合、プログラムがその出力をバッファし、決して書き込むことがない問題が生じる可能性があります。grep や類似のプログラムは、パイプに書き込むときはブロックバッファリングをデフォルトで使用し、ターミナルに書き込むときはラインバッファリングを使用します。これが、"tail -f /some/log/file | grep thing1 | grep thing2" というコマンドが出力を見せない理由です。grep、sed、awk、tcpdump、jq などのコマンドがバッファリングを行い、tail、cat、tee などのコマンドはバッファリングしません。C、Python、Ruby、Perl などのプログラミング言語もバッファリングを行い、バッファリングを無効にするさまざまな方法があります。パイプに Ctrl-C を押すと、プログラムの出力バッファが失われる可能性があります。シグナルが受信される前にバッファがフラッシュされることがないためです。ファイルにリダイレクトするときもバッファリングが起こりますが、一般的に予想通りの動作を示し、プログラムが終了する前にバッファの内容が書き込まれます。バッファリングを避けるには、速く終了するプログラムを実行する、grep に "--line-buffered" フラグを使用する、awk を使用してコマンドを書き換える、stdbuf を使用する、unbuffer を使用してプログラムがターミナルに書き込むように強制するなどの方法があります。最適なソリューションは、特定の状況によって異なります。unbuffer は、信頼できる選択肢です。バッファリングは、一般的に問題とはならないが、パイプにデータが遅く追加される場合に生じる可能性があります。バッファリングを無効にする環境変数があれば便利ですが、そのデザインと実装には課題があります。