Bash は coproc を待つ前に *_PID 変数を設定解除します。

Bash は coproc を待つ前に *_PID 変数を設定解除します。

使ってみよう共同プロセス非同期プロセスの出力を別のシェルコマンドにパイプし、非同期プロセスの終了状態を確認します。

coproc LS { ls dir; }
while IFS= read i; do echo "$i"; done <&"$LS" # Do something with the output.
wait "$LS_PID"; echo $? # Check exit status.

問題は、上記のコードが少なくともBashでは機能しないことです4.3.46(1)-releasewhileこのステートメントを実行した後、Bashは設定を解除します$LS_PID(おそらくプロセスが終了したことを認識したからです)。呼び出しwaitプロセスはまだ有効です。たとえば、次のようになります。

coproc LS { ls dir; }
P=$LS_PID
while IFS= read i; do echo "$i"; done <&"$LS" # Do something with the output.
wait "$P"; echo $? # Check exit status.

これは、ディレクトリが存在するかどうかによって印刷または異なります02そのため、PIDを別の変数に保存する必要がありますが、それは不便です。しかし、私が興味を持っているのはなぜこれが起こるのか、そして私がそれに影響を与える可能性があるのか​​ということです。

プロセスを開始する$LS_PID前になぜ設定されていないのですか?waitこの動作はどこかに文書化されていますか?コマンド出力を使用して終了コードを確認することが一般的なユースケースであると考えられる簡単な回避策はありますか?

答え1

COPROC_PIDこれはBashマニュアルには記載されていませんが、この変数の期待される動作です。

正しい解決策は、すでに行ったことを正確に行うことです。$COPROC_PIDcoprocessが終了したときに設定されない変数に値を格納します。

になります。いいえPIDを取得する前にコルーチンが終了した場合に機能するため、変数を使用する前に変数に値があることを確認するのが賢明かもしれません。

引用:http://gnu-bash.2382.n7.nabble.com/Several-issues-with-coprocesses-regarding-exit-status-td11125.html

関連情報