web-dev-qa-db-ja.com

「tail -f」出力を別のファイルに書き込む

私の最後の投稿 からの続きとして、「まれな」イベントの発生を見つけるためにgrep & tail -fを使用しました。これを別のファイルに記録したいと思います。

私は回してみました

tail -f log.txt | egrep 'WARN|ERROR'

tail -f log.txt | egrep 'WARN|ERROR' | tee filtered_output.txt

ファイルは作成されますが、何も入力されていません。これはキャッシュの問題なのでしょうか。新しいファイルに尾の出力をリアルタイムで追加するにはどうすればよいですか?

36
Mike

バッファリングが問題です。

このようにしてください

 tail -f log.txt | egrep --line-buffered 'WARN | ERROR' | tee Filtered_output.txt 
#^^^^^^^^^^^^^^^ 

Cygwinでも動作することを確認しました。

45
nik

おそらくバッファリングの問題です。これを参照してください パイプを使用する場合の自動バッファリングの無効化に関する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 2unbufferはCygwinでexpectソースパッケージから入手できます(例 expect-20030128 -1-src.tar.bz2expect/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としてインストールされます。

6
quack quixote

実際に「終了」しないコマンド(tail -fなど)を使用する場合、これは実際には機能しないか、まったく機能しません。

出力をテキストファイルにリダイレクトできるはずです。これを試して:

tail -f log.txt | egrep 'WARN|ERROR' > filtered_output.txt
4
Josh Hunt

他の人が指摘したように、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
}