私の最後の投稿 からの続きとして、「まれな」イベントの発生を見つけるためにgrep & tail -f
を使用しました。これを別のファイルに記録したいと思います。
私は回してみました
tail -f log.txt | egrep 'WARN|ERROR'
に
tail -f log.txt | egrep 'WARN|ERROR' | tee filtered_output.txt
ファイルは作成されますが、何も入力されていません。これはキャッシュの問題なのでしょうか。新しいファイルに尾の出力をリアルタイムで追加するにはどうすればよいですか?
バッファリングが問題です。
このようにしてください
tail -f log.txt | egrep --line-buffered 'WARN | ERROR' | tee Filtered_output.txt #^^^^^^^^^^^^^^^
Cygwinでも動作することを確認しました。
おそらくバッファリングの問題です。これを参照してください パイプを使用する場合の自動バッファリングの無効化に関するSOの投稿 。 unbuffer
からexpect
コマンドを使用できます。
$ unbuffer tail -f log.txt | egrep 'WARN|ERROR' | tee filtered_output.txt
Edit:パイプラインが長いため、各コマンドのバッファリングを解除する必要があります(最後のコマンドを除く)。
$ unbuffer tail -f log.txt | unbuffer egrep 'WARN|ERROR' | tee filtered_output.txt
Edit 2:unbuffer
はCygwinでexpect
ソースパッケージから入手できます(例 expect-20030128 -1-src.tar.bz2 、expect/examples
フォルダにあります)が、非常に短いスクリプトです。 expect
パッケージがすでにインストールされている場合は、これを/usr/local/bin
ディレクトリのunbuffer
というスクリプトに追加するだけです。
#!/usr/bin/expect --
# Description: unbuffer stdout of a program
# Author: Don Libes, NIST
eval spawn -noecho $argv
set timeout -1
expect
Debianでは、unbuffer
コマンドはexpect-dev
パッケージで提供され、expect_unbuffer
としてインストールされます。
実際に「終了」しないコマンド(tail -f
など)を使用する場合、これは実際には機能しないか、まったく機能しません。
出力をテキストファイルにリダイレクトできるはずです。これを試して:
tail -f log.txt | egrep 'WARN|ERROR' > filtered_output.txt
他の人が指摘したように、Expectのunbuffer
ユーティリティを使用できます。
ただし、システムおよび使用可能なExpectのバージョンによっては、-p
スイッチを使用してバッファリングを解除する必要がある場合があります。 manページの引用:
Normally, unbuffer does not read from stdin. This simplifies use of unbuffer in some situations. To use unbuffer in a pipeline, use
the -p flag. Example:
process1 | unbuffer -p process2 | process3
したがって、次の呼び出しが必要になる場合があります。
unbuffer -p tail -f log.txt | unbuffer -p egrep 'WARN|ERROR' | tee filtered_output.txt
ところで、出力バッファリング問題の完全な説明については、この記事を参照してください: http://www.pixelbeat.org/programming/stdio_buffering/
これは私が持っているunbuffer
のバージョンです:
#!/usr/bin/expect --
# Description: unbuffer stdout of a program
# Author: Don Libes, NIST
if {[string compare [lindex $argv 0] "-p"] == 0} {
# pipeline
set stty_init "-echo"
eval spawn -noecho [lrange $argv 1 end]
close_on_eof -i $user_spawn_id 0
interact {
eof {
# flush remaining output from child
expect -timeout 1 -re .+
return
}
}
} else {
set stty_init "-opost"
set timeout -1
eval spawn -noecho $argv
expect
}