ここに何かが抜けたようです。
#!/bin/bash
timeout 5 sleep 10 &
parent_pid=$( ps --pid $! -o ppid --no-headers )
timeout_pid=$( pgrep --parent $parent_pid timeout )
wait $timeout_pid
echo "exit code: $?"
スクリプトを呼び出しwait-pid
て、次を実行します。
$ ./wait-pid
exit code: 124
これが私が期待するものです。プロセスをtimeout
終了して124で終了すると、忠実に返されます。sleep
wait
しかし、初期コマンドにパイプを追加すると、次のようになります。
timeout 5 sleep 10 | cat &
parent_pid=$( ps --pid $! -o ppid --no-headers )
timeout_pid=$( pgrep --parent $parent_pid timeout )
wait $timeout_pid
echo "exit code: $?"
今私は次を得ます:
$ ./wait-pid
exit code: 0
wait
待っているプロセスの終了コードを返さないでくださいtimeout
。それでは、終了コードはまだ124でなければなりませんか?
これはbash 4.4.20(1)リリースバージョンです。
答え1
私はbashメーリングリストにある非常に深刻なGreg Wooledgeから返信を受けました。重要な要素は次のとおりです。
wait コマンドは、「非同期コマンド」とも呼ばれるシェルの直接サブプロセスでのみ機能します。非同期コマンドがパイプの場合、元のsh機能セットに置き換えられます。非同期コマンドの終了状態はパイプラインの最後のコマンドの終了状態であり、他のコマンドの終了状態は単に削除されます。
timeout
そのため、パイプにいるときに終了コードを取得できない理由です。
私が望む動作を取得する方法は、一時ファイルを使用して非同期コードから終了コードをキャプチャすることです。それは次のとおりです。
{
timeout 5 sleep 10 | cat
echo "${PIPESTATUS[@]}" > "$tempfile"
} &
wait