Tシャツがパイプから出力全体を取得しない


11

次のようなコマンドを実行するスクリプトがあります。

export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH;./some_app -i $INDEX | tee $LOG
echo "Number of errors: $(grep "ERROR" $LOG | wc -l)"

問題はおそらくへのパイプにありteeます。出力全体が得られていないようです。アプリケーションが終了すると、出力の最後の数行(通常、致命的なエラーを含む行)が失われます。パイプなしでアプリを実行teeすると、出力に表示されます。

スクリプトでT型がすべての出力の処理を完了するまで待機させるにはどうすればよいですか?


stdoutではなく、ファイルにティーインしても問題ありませんか?
Pilot6 2015年

回答:


22

致命的なエラーはSTDOUT(1)ではなく、STDERR(2)で発生している可能性があります。STDERRをSTDOUTにリダイレクトする2>&1と、パイプもそれをキャプチャする必要があります。

./some_app -i $INDEX 2>&1 | tee $LOG

上部にバッファリングの問題がある場合は、バッファリングされていない状態にすることができます。

stdbuf -o0 ./some_app -i $INDEX 2>&1 | tee $LOG

よし、近づいてきている。致命的なエラーが出力されているのがわかりますが、完全ではありません。エラーのある行は途中で終了し、エコー出力が続行されます。バッファをフラッシュするか、単にその部分が完了するのを待つだけで、まだいくつかの問題があります。
Ladislav Mrnka、2015年

編集。私の経験ではかなりまれですが、終了時に何かが完全にバッファをすり抜けますが、一見の価値があります。
オリ

1
できた!ありがとうございました。質問が多すぎるかもしれませんが、他のプロセスにパイプするときにバッファリングをオフにする必要がある理由を誰かが理解していますか?
Ladislav Mrnka、2015年

@オリとてもいいです!
Pilot6 2015年

6

エラーメッセージは通常STDERR(ファイル記述子2)に表示されるため、STDOUTとSTDERRの両方を次のようにリダイレクトする必要がありますtee

./some_app -i "$INDEX" |& tee "$LOG"

その場合./some_app -i $INDEX | tee $LOG、STDOUTをにリダイレクトするだけteeです。

|& STDOUTとSTDERRの両方がリダイレクトされます。

STDOUTのみをリダイレクトすることができない場合(従来どおり):

./some_app -i "$INDEX" | tee "$LOG"

一方、STDERRのみをリダイレクトする場合:

./some_app -i "$INDEX" 2>&1 >/dev/null | tee "$LOG"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.