web-dev-qa-db-ja.com

「tail -f」バッファをフラッシュしますか?

次のステートメント(簡略版)を使用しています。

tail -f -c+1 <filename>

ファイルをプロセスにパイプするため。

しかし、私が見つけたのは、パイプでつながれていない行の最後にたくさんの行があるということです。

具体的な例は、mysqlファイルをパイプし、最後に達したときに停止することです。

tail -f -c+1 mysqdump.sql | sed '/^-- Dump completed/ q0'

これは機能しません-ダンプの最後の行-- Dump completed [...]はsedにパイプされていません。

私の推測では、tail -fバッファは、この場合、いっぱいになったときにのみフラッシュされます。

これを回避する方法を誰かが知っていますか?

=================

私は原因を見つけました-説明は完全ではありません(そしてコードは動作を示していません)。

この問題は、圧縮(lzma)ファイルからパイプするときに発生します。

tail -f -c+1 <filename.lzma> | lzma -d | sed '/^-- Dump completed/ q0'

ほとんどの場合、tailは最後の圧縮ブロックを送信していません。これは、入力がバイナリであるため、新しい行が検出されないためです。

7
Marcus

tail -fは、すべての入力行の後にフラッシュします。これはstrace(またはtrussまたはプロセスのシステムコールをトレースするためにUNIXバリアントが提供するもの)で確認できます。

不完全な行がある場合は、tail -fは次の改行を待ち続けます。テキストファイル用に設計されたツールです。バイナリファイルをテールする必要がある場合(例:-- Dump completedの後には改行がありません)。カスタムツールを使用する必要があります。

sedの出力をターミナルからリダイレクトすると、独自のバッファリングが行われます。 stdbufまたはunbuffer を試してください。

stdbuf -o0を使用した例。参照: https://superuser.com/a/1123674/126847

tail -F cpu.log | stdbuf -o0 tr '=' ' ' | stdbuf -o0 awk '$6 > 1'
2
JohnMudd