24
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

シェルスクリプト wait コマンド

Posted at
wait コマンドを使うケース

シェルスクリプトでバックグラウンドで別のプロセスを動かしたい(並列処理させたい)。
ただ、シェルスクリプトの終了はバッググラウンドのプロセス終了も待ちたい。
wait コマンドにバックグラウンドのプロセスIDを渡すことで、そのプロセスが終了するまで待つ動きになります。
※もし wait コマンドを使わなければ、たとえバックグラウンドのプロセスがまだ終わってなかったとしても、フォアグラウンドでの処理がすべて終われば、シェルスクリプトは終了します。

バッググラウンドのプロセス終了を待つ
  1. echo "Start background sleep" が実行されます。
  2. サブシェルで sleep 10 コマンド(10秒待つ)をバックグラウンドで実行されますが、バックグラウンドなので、すぐに次の行の echo "Start foreground sleep" が実行されます。
  3. フォアグラウンドで sleep 5 コマンド(5秒待つ)を実行されます。
  4. 5秒後、sleep 5 コマンドが終了し、echo "End foreground sleep" が実行されます。
  5. wait $! コマンドがあるため、直近で実行されたバックグラウンドプロセス(即ちサブシェル)の終了を待ちます。
  6. さらに5秒後(スタートから10秒後)にサブシェル内の sleep 10 コマンドが終了します。
  7. 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)の結果が保持されます。

24
19
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?