Grep がパイプへの出力に失敗しましたか?

Grep がパイプへの出力に失敗しましたか?

makeの出力のgrepフィルタリングに問題があります。特に、

make target 2>&1 | grep -E --color=never "^make.*"

期待どおりに動作しますが、次の例ではコンソールに出力が何も表示されません。

make target 2>&1 | grep -E --color=never "^make.*" | cat

何か明らかなことを見逃しているのでしょうか? 最初のコマンドは出力するのに、2 番目のコマンドは出力しないのはなぜでしょうか? 何らかの IO バッファリングと関係があるのでしょうか? それとも私が愚かなのでしょうか?

[編集]: cat実際に使用したいコマンドの最小限のテスト ケース プレースホルダーです。

[編集]:これはgrepの問題ではないようです。ああ同じ動作につながります。

[編集]:cat がプレースホルダーとなっているスクリプト:

#!/bin/bash
cat - \
 | grep -E --color=never "^.*warning:.*|^.*error:.*|^make.*[Ee]rror.*|^make.*" \
 | hilite.sh -r "^.*warning:.*" -f yellow -B \
 | hilite.sh -r "^.*error:.*" -f red -B \
 | hilite.sh -r "^make.*[Ee]rror.*" -f red -B \
 | hilite.sh -r "^make.*" -f magenta

[編集]:バッファリング/IO の問題だと思います。ビルドを週末まで実行したままにして、必要な場所に出力が最終的に得られるかどうかを確認します。

答え1

おそらくgrep、TTY に書き込んでいないことを検出しているため、通常の行バッファリング モード (つまり、見つかった各行が表示されます) で動作するのではなく、より多くの出力をバッファリングします。この動作は、write()システム コールが少なくなるため効率的ですが、パイプライン出力を待っているユーザーにとっては、少し誤解を招く可能性があります。

GNU を使用している場合grep(Linux タグに基づいて推測しますが)、より一般的な行バッファ モードで動作するように--line-buffered強制するオプションを確認してください。これにより、技術的にはパフォーマンスが低下する可能性があります(man ページに記載されているとおり) が、ライブ ビルドの出力を見ているので、その点では違いはないと思われます。grepgrep

答え2

コマンドが何をするのかよくわかりません。ファイル名に make.* が含まれるファイルを cat しますか?

catforを変更してみてはいかがでしょうかxargs cat?

答え3

例えば、次のようなことを試してみるといいでしょうunbuffer

make target 2>&1 | unbuffer -p grep -E --color=never "^make.*" | cat

関連情報