web-dev-qa-db-ja.com

grepを2回使用すると出力が表示されないのはなぜですか?

基本的に、なぜこれが何も出力しないのか疑問に思っています:

tail --follow=name file.txt | grep something | grep something_else 

あなたはそれが確認するために別の行を実行した出力を生成するはずだと仮定することができます

cat file.txt | grep something | grep something_else

Tailの出力を複数回パイプできないようです!?誰もが契約が何であるかを知っており、解決策はありますか?

編集:これまでの質問に答えるために、ファイルには間違いなくgrepによって表示されるべき内容が含まれています。 grepが次のように実行されている場合の証拠として:

tail --follow=name file.txt | grep something

出力は正しく表示されますが、これが代わりに使用される場合:

tail --follow=name file.txt | grep something | grep something

出力は表示されません。

役に立つ場合は、ubuntu 10.04を実行しています

41
radman

また、パイプ内でgrepのバッファリングに問題が発生する場合があります。つまり、出力は表示されません

   tail --follow=name file.txt | grep something > output.txt

grepは独自の出力をバッファリングするためです。

これを回避するには、grepで--line-bufferedスイッチを使用します。

tail --follow=name file.txt | grep --line-buffered something > output.txt

フォローの結果をできるだけ早くoutput.txtファイルに入れたい場合に便利です。

87
simonc

ここで何が起こっているかを把握しました。コマンドが機能していることがわかりますが、出力がコンソールに到達するまでに長い時間がかかるだけです(私の場合は約120秒です)。これは、標準出力のバッファが各行ではなく各ブロックに書き込まれるためです。そのため、書き込み中にファイルのすべての行を取得する代わりに、2分ごとに巨大なブロックを取得します。

これは正しく機能することに注意してください:

tail file.txt | grep something | grep something

問題があるのは、--follow=nameを含むファイルの次です。

私の目的のために、私はそれを回避する方法を見つけました、私がやろうとしていたことは、ファイルへの最初のgrepの出力をキャプチャすることでしたので、コマンドは次のようになります:

tail --follow=name file.txt | grep something > output.txt

これを回避する方法は、次のようにscriptコマンドを使用することです。

script -c 'tail --follow=name file.txt | grep something' output.txt

スクリプトはコマンドの出力をキャプチャしてファイルに書き込み、2番目のパイプを回避します。

これにより、この問題を効果的に回避できました。コマンドが期待どおりに機能しなかった理由を説明し、問題を解決しました。

参考までに、これらの他のスタックオーバーフローの質問は関連しています:
パイプではなく、stdinがインタラクティブであるとアプリケーションをだます
Pythonを使用して別のプログラムの標準出力を強制的にバッファリング解除します

6
radman