端末のシェル(bashなど)にはwaitというコマンドがある。
機能
waitは現在操作しているシェルにおけるバックグラウンドのジョブが終了するまで待機するコマンドで、シェルの内部コマンドとなっている(シェルの系統によっては挙動が異なる)。bash,dash,zshでは待機中にCtrl+Cを押すと待機をキャンセルしてプロンプトに戻ることができるが、csh系ではできない?
下はxtermを用いた作業例だが、dashではバックグラウンドで実行した際のジョブ番号やプロセスIDの表示はされない。
(バックグラウンドでxtermを起動することにする) $ xterm & [1] [プロセスIDが表示される] (xtermを終了するまで待機) $ wait (待機状態となり、xtermを終了するとwaitコマンドは終了してプロンプトが出る)
ジョブが複数存在する場合、全てのジョブの終了を待機する。
(3つのバックグラウンドジョブを準備) $ xterm & [1] [xtermのプロセスIDが表示される] $ xmessage test & [2] [xmessageのプロセスIDが表示される] $ zenity --info & [3] [zenityのプロセスIDが表示される] (3つ全てを終了するまで待機) $ wait (3つ全てを終了するとwaitコマンドは終了してプロンプトが出る)
bash,dash,zshでは引数に「%[ジョブ番号]」やプロセスIDを付けることで単独のジョブの終了を待機することもできる(csh系は引数を受け付けない)。
(3つのバックグラウンドジョブを準備) $ xterm & [1] [xtermのプロセスIDが表示される] $ xmessage test & [2] [xmessageのプロセスIDが表示される] $ zenity --info & [3] [zenityのプロセスIDが表示される] (特定のジョブが終了するまで待機) $ wait %2 (2番のジョブ・ここではxmessageを終了するとwaitコマンドは終了してプロンプトが出る)
ただし、プロセスIDを指定する場合、そのシェルから起動された(子)プロセスでないものは対象にはできない。
(bashの場合) bash$ wait [プロセスID] bash: wait: pid [指定したプロセスID] はこのシェルの子プロセスではありません (zshの場合) zsh$ wait [プロセスID] wait: pid [指定したプロセスID] is not a child of this shell (dashでは子プロセス以外のプロセスIDを指定すると何も起こらずに終了する)
用途
シェルスクリプトの中でバックグラウンドでの起動(「[コマンド...] &」)を用いて処理を並列化した場合の同期として使うことができる。他にも、下のようなちょっとした遊びに使うという使い方がある。
#! /bin/sh # 5つのxmessageのウィンドウを閉じるまでの大体の時間を測定する # 表示されるまでの起動処理の時間もカウントされる上に # 秒単位の測定なので、正確ではない PATH=/bin:/usr/bin for i in $(seq 5); do xmessage "CLOSE ME..." & done START=$(date +%s) wait END=$(date +%s) echo "全てのウィンドウを閉じるのにかかった時間は約" $((${END} - ${START})) "秒でした"
使用したバージョン: