別のプログラムを監視する Bourne シェル (/bin/sh) スクリプト (移植性のため) があります。他のプログラムを開始し、それが終了するのを待ちます。2 番目のプログラムが終了すると、最終的な作業を行って終了します。問題は、スクリプトがシグナル (USR2 など) にも応答し、それらのシグナルが表示されたときに何らかの処理を行う必要があることです。
私の素朴な実装は次のとおりです。
#! /bin/sh
echo $$
trap 'echo Respond to USR2' USR2
/bin/sleep 120 &
pid=$!
wait $pid
echo $pid exited with $?
echo Doing final cleanup
これはうまくいきません。シェル SIGUSR2 を送信すると、トラップは期待どおりに起動しますが、wait も終了し、140 が返されます。/bin/sleep は順調に進んでいます。典型的な出力:
28849
Respond to USR2
28850 exited with 140
Doing final cleanup
この動作は、私が便利にアクセスできる 2 つの Bourne シェルの派生物である、dash と bash の間で一貫しています。
私の現在の回避策は、kill でプローブして、子 PID が消えるのを待ってループをスピンすることです。スピン ループは無駄に思えます。また、PID が急速に再利用されている場合、スクリプトが誤って間違ったプロセスを待機している可能性があるウィンドウが拡大します。
#! /bin/sh
echo $$
trap 'echo Respond to USR2' USR2
/bin/sleep 15 &
pid=$!
while /bin/kill -0 $pid 2> /dev/null; do
echo waiting...
sleep 2
done
echo Doing final cleanup
別のプロセスが終了するのを同時に待機し、シグナルに応答できるようにするという私の目標を考えると、より良い解決策はありますか?