プロセス置換を使用してエラーを検出する方法

プロセス置換を使用してエラーを検出する方法

この質問は次の質問に似ています。協会ただし、コマンドライン(bashシェル)の使用に焦点を当てます。

簡単な例を使用して次のコマンドを実行するとき:

$ cat <(date); echo $?
Fri Jul  7 21:04:38 UTC 2017
0

予想通り、終了値は 0 です。

次のコマンドは意図的にエラーを生成しますが、戻り値はまだ0です。

$ cat <(datE); echo $?
bash: datE: command not found...
Similar command is: 'date'
0

コマンドラインで実行するとき(つまり、スクリプトに入れなくても)プロセスの置き換えで発生するエラーをキャッチする方法はありますか?

上記のリンクのソリューションは、コマンドを実行するスクリプトを終了します。

ベストアンサー1

では、bashプロセスの交換はバックグラウンドジョブから始まります。次のコマンドを使用して最後のプロセスリーダーのpidを取得し、他のバックグラウンドジョブと同様に終了ステータスを取得$!できます。wait thatpid

$ bash -c 'cat <(exit 3); wait "$!"; echo "$?"'
3

diff <(cmd1) <(cmd2)同じコマンドで2つのプロセス置換を使用する必要がある場合(表示されているように)、これは役に立ちません。

$ bash -c 'cat <(exit 3) <(exit 4); wait "$!"; echo "$?"'
4

上記のPIDがexit 3ありません。

次のトリックを使用して復元できます。

unset -v p1 p2
x='!'
cat <(exit 3) ${!x#${p1=$!}} <(exit 4) ${!x#${p2=$!}}

両方のPIDが保存されていますが、$p1最後のPIDのみがシェルの作業テーブルに挿入され、拒否待機が誤って要求するため、$p2これは役に立ちません。wait$p1この殻の子ではありません$p1、まだ終了していない場合でも:

$ cat test-script
unset -v p1 p2
x='!'
set -o xtrace
cat <(echo x; exec >&-; sleep 1; exit 3) ${!x#${p1=$!}} <(exit 4) ${!x#${p2=$!}}
ps -fH
wait "$p1"; echo "$?"
wait "$p2"; echo "$?"
$ bash test-script
++ echo x
++ exec
++ sleep 1
+ cat /dev/fd/63 /dev/fd/62
++ exit 4
x
+ ps -fH
UID        PID  PPID  C STIME TTY          TIME CMD
chazelas 15393  9820  0 21:44 pts/4    00:00:00 /bin/zsh
chazelas 17769 15393  0 22:19 pts/4    00:00:00   bash test-script
chazelas 17770 17769  0 22:19 pts/4    00:00:00     bash test-script
chazelas 17772 17770  0 22:19 pts/4    00:00:00       sleep 1
chazelas 17776 17769  0 22:19 pts/4    00:00:00     ps -fH
+ wait 17770
test-script: line 6: wait: pid 17770 is not a child of this shell
+ echo 127
127
+ wait 17771
+ echo 4
4
$ ++ exit 3

詳しくは以下をご覧ください。@mosvyの返信到着非同期ジョブを実行し、bashから終了コードと出力を取得します。

おすすめ記事