エラーが発生した場合にのみパイプ接続は可能ですか? [閉鎖]

エラーが発生した場合にのみパイプ接続は可能ですか? [閉鎖]

エラーがある場合は、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_programfilter_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

関連情報