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 ページに記載されているとおり) が、ライブ ビルドの出力を見ているので、その点では違いはないと思われます。grep
grep
答え2
コマンドが何をするのかよくわかりません。ファイル名に make.* が含まれるファイルを cat しますか?
cat
forを変更してみてはいかがでしょうかxargs cat
?
答え3
例えば、次のようなことを試してみるといいでしょうunbuffer
。
make target 2>&1 | unbuffer -p grep -E --color=never "^make.*" | cat