tail -f からのパイプを使用した grep と sed はキャッシュしているようです

tail -f からのパイプを使用した grep と sed はキャッシュしているようです

特別なログを監視するための実用的なシステムを取得しようとしています。通常、grepとパイプを使用して抽出する非常に特殊なパターンが必要ですtail -f。grep はすべてを出力せず、一部の行をバッファリングしたままにすることに気付きました。すべてを出力してから終了してストリームを閉じるパイプがある場合は、それが理にかなっていると思います。
しかし、それではtail -fうまくいきません。

同じ問題が で発生しますsed

使用したいコマンドの例を次に示します。

clear && tail -F -n1000 /var/log/fail2ban.log | grep 'WARNING.*Ban' | sed s/'fail2ban.actions: WARNING '//g | grep -E --color 'ssh-iptables-perma|$'

例を挙げると:

上記のコマンドの最後の行は次のとおりです。

2015-05-04 11:17:24,551 [ssh-iptables] Ban x.x.x.x

このコマンドを使用すると:

clear && tail -F -n1000 /var/log/fail2ban.log | grep 'WARNING.*Ban' | sed s/'fail2ban.actions: WARNING '//g

最後の行は次のようになります:

2015-05-04 19:45:17,615 [ssh-iptables] Ban y.y.y.y

さらにパイプを削除すると、最新のエントリにさらに移動します。

パイプ内でのこのキャッシュをどうしたら回避できるでしょうか?

答え1

grepのオプション--line-bufferedsedのオプションを追加します--unbuffered

答え2

grepのオプションを使用します--line-buffered

デフォルトでは、ユーティリティは標準出力が端末である場合は行バッファリングを使用しますが、出力がファイル記述子またはパイプに接続されている場合は、より大きなバッファ (おそらく 4 または 8 kB) を使用します。

幸運なことに、 はtail -Fデフォルトで行バッファリングを使用し、grepそれを有効にするコマンドライン オプションがあります。任意のコマンドに対して行バッファリングを有効にする一般的な方法は知りません。

関連情報