tail -f path
上記はファイルへの変更を即座に出力しますが、出力にフィルターを適用し、キーワードxxx
が含まれている場合にのみ表示します。
これにどのように取り組みますか?
Unixでは、あるプログラムの出力を別のプログラムにパイプすることができます。
したがって、尾をフィルタリングするには、grepを使用できます。
tail -f path | grep your-search-filter
短い答え:_tail -f somefile | grep somepattern
_
ただし、これでは不十分な傾向があります。頻繁にローテーションされるファイルをテーリングしているとしましょう(デバッグログの場合、複数回ローテーションされる可能性があります)。その場合、_tail -F
_はあなたの友達です。違いを調べさせていただきます。
しかし、_tail -f
_と_tail -F
_は最初に一連の行を出力します。これは、多くの場合、このユースケースでは望ましくないため、この場合は_-n0
_を追加します
_tail -F -n0 somefile | grep somepattern
_
他のフィルタリングを実行するまでは問題ありませんが、バッファリングに注意する必要があります。 stdoutは、デフォルトでラインバッファリングされます端末への書き込み時ですが、パイプへの書き込み時に完全にバッファリングされます。したがって、tail
は明示的にラインバッファリングされている(または各行の終わりで出力がフラッシュされる)ため、次のコードはそれらが見つかるとすぐにラインを発行し、grep
も出力が端末に送られるためラインバッファリングされます。
_tail -F -n0 somefile | grep somepattern
_
しかし、次に、awk
やcut
などを使用して、出力をさらに処理することにします。
_tail -F -n0 somefile | grep somepattern | awk '{print $3}'
_
そして今、あなたはあなたの出力がどこに行ったのか不思議に思います...ログの量によっては、あなたは出力を得ることがわかるかもしれませんが、grep
の標準出力が完全にバッファリングされた方法で動作しているので、それは一度にページになります、したがってawk
は一度に4kBの入力を受け取ります(デフォルト)。
この場合、_--line-buffered
_オプションを使用することで、grep
にstdout行を常にバッファリングするように指示できます。
_tail -F -n0 somefile | grep --line-buffered somepattern | ...
_
ただし、ほとんどのコマンドには_--line-buffered
_のようなものはありません。よりスクリプト可能なツールの場合は、関数を使用して出力をフラッシュできます(たとえば、awk
では、関数はfflush()
で、Cと同じ名前を共有します。PerlやPythonも同様です)。
cut
のようなものを使用すると、運が悪くなる可能性があります。 ...しかし、unbuffer
を検索してみてください。これは、expect
ツールチェーンによって提供されたものだと思います(私はこれを使用したことがありません)。
これがお役に立てば幸いです。
乾杯、キャメロン
複数のパイプとgrepsを使用して、grep -vで除外したり、grep -iで大文字と小文字を区別しないようにしたりできます。
例:tail -100f/var/log/messages | grep -V ACPI | grep -i ata
末尾から100行のテーリングを開始し、テーリングを維持します。最初にACPIの行を除外し、次にata、ATA、またはそれらの組み合わせの行を表示します。
もう1つの便利なものは、ABCオプションで、After、Before、Contextの各行(前後の行)です。