![エラーが発生した場合にのみパイプ接続は可能ですか? [閉鎖]](https://linux33.com/image/181332/%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%8C%E7%99%BA%E7%94%9F%E3%81%97%E3%81%9F%E5%A0%B4%E5%90%88%E3%81%AB%E3%81%AE%E3%81%BF%E3%83%91%E3%82%A4%E3%83%97%E6%8E%A5%E7%B6%9A%E3%81%AF%E5%8F%AF%E8%83%BD%E3%81%A7%E3%81%99%E3%81%8B%EF%BC%9F%20%5B%E9%96%89%E9%8E%96%5D.png)
エラーがある場合は、2>&1を実行して別のプログラムにパイプ(|)します。それ以外の場合は、2>&1を実行してパイプしないでください。
答え1
だからあなたは走りたい
main_program 2>&1 | filter_program
ただし、filter_program
失敗ステータスが返された場合にのみ実行する必要があります。main_program
プログラムの状態は、実行が完了するまでは不明です。したがって、プログラムが失敗した場合にのみ出力を処理するには、プログラムの実行中にプログラムの出力を保存し、プログラムが完了した後に出力処理コマンドを発行するか、または出力を破棄する必要があります。この答えは、「出力」を使用してstdoutとstderrの組み合わせ出力を意味します。 stdoutを別々に処理するには、追加の作業が必要な場合があります。
出力が小さくテキストのみがある場合は、出力を保存してシェル変数にステータスを返すことができます。ほとんどのシェルは変数でバイナリデータをサポートしていないため、バイナリデータ(ヌルバイトを含むデータ)では機能しません。
error_output=$(main_program 2>&1; echo ".$?")
error_status=${error_output##*.}
error_output=${error_output%.*}
if [ "$error_status" -ne 0 ]; then
printf %s "$error_output" | filter_program
fi
出力が大きいかバイナリの可能性が高い場合は、一時ファイルに保存してください。
output_file=$(mktemp)
main_program >"$output_file" 2>&1
if [ "$?" -ne 0 ]; then
filter_program <"$output_file"
fi
rm -f -- "$output_file"
(省略:信号の一時ファイルを削除するコードです。)
(入力がパイプから来ることが重要な場合は置き換えられますfilter_program <"$output_file"
。)<"$output_file" cat | filter_program
filter_program
基本プログラムが失敗時にのみ出力を生成する場合は、終了状態を待つのではなく、フィルターが出力を生成した直後に開始できます。これifne
ユーティリティは以下から来ます。その他のユーティリティこれに非常に便利です。
main_program 2>&1 | ifne filter_program
答え2
を探す名前付きパイプこのように:
## Create a named pipe
$ mkfifo errorPipe
## In another shell session, launch whatever program you want to pipe the
## error to, telling it to read from errorPipe
$ errorCommand < errorPipe
##$ wc -l errorPipe
1 errorPipeプログラムを実行し、stderrを名前付きパイプ$ yourCommand 2> errorPipeにリダイレクトします。
これによりエラーのみが表示されますerrorCommand
。
$ mkfifo errorPipe
$ wc -l < errorPipe ## this will hang until I write something to errorPipe
次に、別の端末を開き、次を実行します。
$ perl -le 'sleep(2);
print "this is stdout";
sleep(2);
print STDERR "this is stderr"' 2>errorPipe
this is stdout
2秒後、this is stdout
現在の端末に何が印刷されているかがわかります。同時に、wc
他の端末から開始したプロセスが終了し、結果が印刷されます。
$ wc -l errorPipe
1 errorPipe