wait コマンドを使うケース
シェルスクリプトでバックグラウンドで別のプロセスを動かしたい(並列処理させたい)。
ただ、シェルスクリプトの終了はバッググラウンドのプロセス終了も待ちたい。
wait コマンドにバックグラウンドのプロセスIDを渡すことで、そのプロセスが終了するまで待つ動きになります。
※もし wait コマンドを使わなければ、たとえバックグラウンドのプロセスがまだ終わってなかったとしても、フォアグラウンドでの処理がすべて終われば、シェルスクリプトは終了します。
バッググラウンドのプロセス終了を待つ
- echo "Start background sleep" が実行されます。
- サブシェルで sleep 10 コマンド(10秒待つ)をバックグラウンドで実行されますが、バックグラウンドなので、すぐに次の行の echo "Start foreground sleep" が実行されます。
- フォアグラウンドで sleep 5 コマンド(5秒待つ)を実行されます。
- 5秒後、sleep 5 コマンドが終了し、echo "End foreground sleep" が実行されます。
- wait $! コマンドがあるため、直近で実行されたバックグラウンドプロセス(即ちサブシェル)の終了を待ちます。
- さらに5秒後(スタートから10秒後)にサブシェル内の sleep 10 コマンドが終了します。
- echo "End background sleep" が実行されます。
wait-example1.sh
echo "Start background sleep"
(
sleep 10
) &
echo "Start foreground sleep"
sleep 5
echo "End foreground sleep"
wait $!
echo "End background sleep"
バッググラウンドのプロセスの終了ステータスを得る
wait $! の後で $? で取得できる。
wait-example2.sh
(
sleep 10
exit 7
) &
wait $!
echo $? # 7
複数のバッググラウンドのプロセスの終了を待つ
wait コマンドに複数のプロセスIDを渡すことで、それらのプロセスがすべて終了するまで待たせることが可能になります。
それでは、以下のように指定した場合、最後の終了ステータス(echo $?の結果)は何になるでしょうか?
wait-example3.sh
(
sleep 3
exit 3
) &
PID1=$!
(
sleep 9
exit 9
) &
PID2=$!
(
sleep 6
exit 6
) &
PID3=$!
wait $PID1 $PID2 $PID3
echo $?
一番最後に終了する 9 と予想したくなりますが、6 が出力されます。
wait コマンドに指定した最後の引数(ここでは $PID3)の結果が保持されます。