
私は次の方法を使用して非常に長いmake出力を配布しようとしています
mkfifo myfifo
make 2>&1 | tee myfifo | grep -E "errors|warnings" myfifo > errors.log | cat myfifo
アイデアとしては、出力のサブセットをログ ファイルにコピーし、出力全体をコンソールの stdout にリダイレクトするというものです。
最初は動作しているように見えますが、突然停止し、Ctrl + Z を押すまでフリーズしたままになります。
プロセス置換の使用
make 2>&1 | tee >(grep -E "errors|warnings" > errors.log)
シェルはデフォルトで厳密な POSIX 準拠でコンパイルされているため、これは不可能です。
プラットフォーム - Ubuntu 風ディストリビューション。シェル bash 4.2 (利用可能なのは 1 つだけ)
答え1
それ
make 2>&1 | tee myfifo | grep -E "errors|warnings" myfifo > errors.log | cat myfifo
P1 P2 P3
コマンドはあまり意味がありません。パイプを挟んで 4 つのコマンドを同時に開始します。
make 2>&1
: stdoutとstderrはP1に送られますtee myfifo
: P1 から stdin、P2 に stdout。したがって、tee
出力は両方myfifo
と P2 に書き込まれます。grep -E "errors|warnings" myfifo > errors.log
: P2 からの stdin ですが、ファイル名 (myfifo
) を に渡しているためgrep
、grep
その stdin からは読み込まれません。 stdout は に送られerrors.log
、P3 には何も書き込まれません。cat myfifo
: P3 からの stdin ですが、やはりcat
ファイル名が指定されているため、代わりにそれを読み取ります。つまり、 と の両方grep
が同時にcat
読み取りますmyfifo
。
P2 からは何も読み込まれないため、tee
P2 がいっぱいになると はハングします。また、によって読み込まれたcat
の部分も表示されません。myfifo
grep
make 2>&1 | tee myfifo | grep -e errors -e warnings > errors.log | cat myfifo
が、あなたが意図しているものに近いと思います。ここでも P3 は使用されませんが、同時に|
開始して待機するために を使用しています。cat
または、次のようにすることもできます。
make 2>&1 | tee myfifo & grep -e errors -e warnings > errors.log
wait
より多くの s が必要な場合はgrep
、より多くの fifo が必要です。
make 2>&1 | tee fifo2grep1 fifo2grep2 &
grep errors fifo2grep1 > errors.log &
grep warnings fifo2grep2 > warnings.log
wait
をサポートするシステムでは/dev/fd/x
、次の操作も実行できます。
make 2>&1 | { tee /dev/fd/3 | grep -e errors -e warnings 3>&-; } 3>&1
(これは通常、それをサポートするシェルでのプロセス置換によって行われることです)。
2 grep
s の場合は次のようになります。
make 2>&1 |
{
{
tee /dev/fd/3 /dev/fd/4 |
grep errors > errors.log 3>&- 4>&-
} 4>&1 |
grep warnings > warnings.log 3>&-
} 3>&1
答え2
grep -E "errors|warnings" myfifo > errors.log
パイプにデータがなくなると、cat myfifo
パイプから読み取る次のコマンドはブロックされます。
質問を正しく理解していれば、すべてのメッセージを stdout に出力し、すべてのエラーおよび警告メッセージを にリダイレクトしたいということですねerrors.log
。したがって、パイプを使用する場合は、次の 2 つを使用します。
mkfifo pipe1 pipe2
make 2>&1 | tee pipe1 pipe2 | grep -E "errors|warnings" pipe1 > errors.log | cat pipe2