2012-01-31 8 views
15

2つの並行プログラム(ログファイルの末尾)の出力をbashの1つの出力ストリームに取り込みたいとします。2つの並行プログラムの出力をbashと組み合わせる

私はテストのために、このプログラム例で使用

function foo { for i in $(seq 1 10); do echo "program $*"; sleep 1; done } 

今すぐ次が

(foo bar & foo baz &) | tee /tmp/output 

正常に動作しませんが、私はミックスに余分なパイプを追加したら、それはもはや作品:

(foo bar | grep bar & foo baz &) | tee /tmp/output # does't work 

出力は順次になります。私はgrepを含む別のプログラムを作ることができましたが、これを回避する方法があるかどうかを知りたいのですが。

誰かがそれがうまくいかない理由を説明できれば、私はとても幸せになるでしょう。

答えて

7

大きな質問!この1つは私を少しだけ困惑させましたが、私は何が起こっているのか知っていると思います。何が起こっているのはgrepが出力をバッファリングしているということです。だから、もしあなたが走らせるなら、最後にすべてが洪水するのを見るでしょう。あなたはGNU grepを使用することが起こる場合--line-バッファリングオプション渡してみてください:推測をハザード

(foo bar | grep --line-buffered bar & foo baz &) | tee /tmp/output 

を、そしてあなたの心それはそれが何であるか、本質的にですが、私はgrepがあるため、より出力をバッファリングしていることを言うと思いますisatty(1)は、経由でTTYの出力を見ていても、ではなく、のTTYへの書き込みであることを示します。より多くの出力をバッファリングすることにより、より少ない数のwrite()コールが作成され、より効率的になります。 grepを実行し、端末の出力を見るのに慣れている行は、バッファされた行です。行は見つかると表示されます。このオプションは、grepを強制的にそのモードで実行します。

マニュアルページで警告されているように、これはgrepにパフォーマンス上の影響を与える可能性があることに注意してください。

+0

「ティーのため」です。 grepはttyへの書き込みではありません。 grepはパイプに書き込みを行い、teeはttyに書き込みを行います。 –

+0

あなたは絶対に正しいです。貧しい言葉を私の部分に - 私は明確にするために自分の投稿を編集します。 – FatalError

1

あなたはfoo barコマンドの出力を待つことはgrepを作っているとbarを持つすべての行がバズラインの後に一度来る理由ですfoo bargrep間のパイプの使用のためです。あなたは本当にコマンドから何かをgrep検索したい場合は、次のように別の関数を定義します。

function foo1 { for i in {1..3}; do echo "program $*" | grep "$*"; sleep 1; done } 

そして実行します。

(foo1 bar & foo baz &) | tee /tmp/output 

今、あなたは、出力のように見えることに気づくでしょう:

program baz 
program bar 
program baz 
program bar 
program baz 
program bar 
... 
... 
関連する問題