[linux] waitコマンドの使い方 – プロセスやジョブの終了を待機

waitコマンドは、指定したプロセスやジョブが終了するまでシェルの実行を一時停止するために使用されます。

引数にプロセスID(PID)やジョブIDを指定することで、そのプロセスやジョブが終了するのを待機します。

引数を指定しない場合、シェルが起動したすべての子プロセスが終了するまで待機します。

終了ステータスは、待機したプロセスの終了コードを返します。

バックグラウンドで実行されるプロセスの管理に便利です。

この記事でわかること
  • waitコマンドの基本的な使い方と動作
  • プロセスIDやジョブIDを指定して待機する方法
  • 複数のプロセスを同時に待機する方法
  • waitコマンドを使ったエラーハンドリングの方法
  • シェルスクリプトでのwaitコマンドの応用例

目次から探す

waitコマンドとは

waitコマンドは、Bashシェルでバックグラウンドプロセスやジョブの終了を待機するために使用されるコマンドです。

通常、シェルスクリプトやコマンドラインで複数のプロセスを並行して実行する際に、特定のプロセスが終了するまで待機したい場合に役立ちます。

waitコマンドを使うことで、指定したプロセスが終了するまで次の処理を実行せずに待機することが可能です。

例えば、複数のバックグラウンドジョブを実行している場合、waitコマンドを使うことで、全てのジョブが完了するまで待機し、その後に次の処理を行うことができます。

また、waitコマンドは終了ステータスを返すため、プロセスが正常に終了したかどうかを確認することもできます。

waitコマンドは、シェルスクリプトの並列処理や、複数のプロセスを効率的に管理する際に非常に便利なツールです。

waitコマンドの使い方

waitコマンドは、プロセスやジョブの終了を待機するために使われます。

ここでは、具体的な使い方をいくつか紹介します。

プロセスIDを指定して待機する

waitコマンドにプロセスID(PID)を指定することで、そのプロセスが終了するまで待機することができます。

以下は、プロセスIDを指定して待機する例です。

# プロセスID 1234 の終了を待機する
wait 1234

このコマンドは、プロセスID 1234 のプロセスが終了するまで次の処理を実行しません。

ジョブIDを指定して待機する

Bashでは、バックグラウンドジョブにジョブIDを割り当てることができます。

waitコマンドにジョブIDを指定することで、そのジョブが終了するまで待機します。

ジョブIDは、%記号を使って指定します。

# バックグラウンドジョブを実行
sleep 10 &
# ジョブID %1 の終了を待機する
wait %1

この例では、sleep 10 &でバックグラウンドジョブを実行し、そのジョブID %1 の終了を待機します。

引数なしで全ての子プロセスを待機する

waitコマンドに引数を指定しない場合、現在のシェルで実行中の全ての子プロセスが終了するまで待機します。

これは、複数のバックグラウンドプロセスを一度に待機したい場合に便利です。

# 複数のバックグラウンドプロセスを実行
sleep 5 &
sleep 10 &
# 全てのバックグラウンドプロセスが終了するまで待機
wait

この例では、sleep 5 &sleep 10 &の両方のプロセスが終了するまで待機します。

複数のプロセスを同時に待機する方法

waitコマンドは、複数のプロセスIDを一度に指定して待機することも可能です。

これにより、特定の複数のプロセスが終了するまで待機することができます。

# 複数のバックグラウンドプロセスを実行
sleep 5 &
pid1=$!
sleep 10 &
pid2=$!
# 複数のプロセスIDを指定して待機
wait $pid1 $pid2

この例では、$pid1$pid2の両方のプロセスが終了するまで待機します。

終了ステータスの取得方法

waitコマンドは、待機したプロセスの終了ステータスを返します。

終了ステータスは、プロセスが正常に終了したかどうかを確認するために使用されます。

終了ステータスは、$?変数に格納されます。

# バックグラウンドプロセスを実行
sleep 5 &
pid=$!
# プロセスの終了を待機
wait $pid
# 終了ステータスを取得
echo "終了ステータス: $?"

この例では、waitコマンドが終了した後に、$?変数を使ってプロセスの終了ステータスを表示します。

waitコマンドの実行例

ここでは、waitコマンドを実際にどのように使うか、具体的な例を紹介します。

単一のバックグラウンドプロセスを待機する例

まずは、単一のバックグラウンドプロセスをwaitコマンドで待機する例です。

バックグラウンドで実行されるプロセスが終了するまで、次の処理を待機します。

# バックグラウンドで sleep コマンドを実行
sleep 5 &
# プロセスIDを取得
pid=$!
# プロセスの終了を待機
wait $pid
# 終了メッセージを表示
echo "プロセス $pid が終了しました"

この例では、sleep 5 &でバックグラウンドプロセスを実行し、そのプロセスIDを$!で取得します。

wait $pidでそのプロセスが終了するまで待機し、終了後にメッセージを表示します。

プロセス 12345 が終了しました

複数のバックグラウンドプロセスを待機する例

次に、複数のバックグラウンドプロセスを同時に実行し、それらが全て終了するまで待機する例です。

# 複数のバックグラウンドプロセスを実行
sleep 3 &
pid1=$!
sleep 5 &
pid2=$!
# 両方のプロセスが終了するまで待機
wait $pid1 $pid2
# 終了メッセージを表示
echo "プロセス $pid1 と $pid2 が終了しました"

この例では、sleep 3 &sleep 5 &の2つのバックグラウンドプロセスを実行し、それぞれのプロセスIDを$pid1$pid2に格納します。

wait $pid1 $pid2で両方のプロセスが終了するまで待機し、終了後にメッセージを表示します。

プロセス 12345 と 12346 が終了しました

シェルスクリプトでのwaitコマンドの活用例

waitコマンドは、シェルスクリプト内で並列処理を行う際に非常に便利です。

以下は、シェルスクリプトで複数のバックグラウンドプロセスを実行し、それらが全て終了するまで待機する例です。

#!/bin/bash
# バックグラウンドで複数の処理を実行
echo "プロセス1を開始します"
sleep 3 &
pid1=$!
echo "プロセス2を開始します"
sleep 5 &
pid2=$!
echo "プロセス3を開始します"
sleep 2 &
pid3=$!
# 全てのプロセスが終了するまで待機
wait $pid1 $pid2 $pid3
# 終了メッセージを表示
echo "全てのプロセスが終了しました"

このシェルスクリプトでは、3つのバックグラウンドプロセスを並行して実行し、それぞれのプロセスIDを取得します。

wait $pid1 $pid2 $pid3で全てのプロセスが終了するまで待機し、終了後にメッセージを表示します。

プロセス1を開始します
プロセス2を開始します
プロセス3を開始します
全てのプロセスが終了しました

waitコマンドの応用

waitコマンドは、基本的な使い方だけでなく、さまざまな応用が可能です。

ここでは、waitコマンドを使った応用的な使い方を紹介します。

複数のプロセスを並列実行し、全ての終了を待つ

複数のプロセスを並列に実行し、それらが全て終了するまで待機することができます。

これにより、複数のタスクを同時に処理し、全てのタスクが完了した後に次の処理を行うことが可能です。

#!/bin/bash
# 複数のバックグラウンドプロセスを実行
echo "プロセス1を開始します"
sleep 3 &
pid1=$!
echo "プロセス2を開始します"
sleep 5 &
pid2=$!
echo "プロセス3を開始します"
sleep 2 &
pid3=$!
# 全てのプロセスが終了するまで待機
wait $pid1 $pid2 $pid3
# 終了メッセージを表示
echo "全てのプロセスが終了しました"

このスクリプトでは、3つのプロセスを並列に実行し、それらが全て終了するまで待機します。

並列処理を行うことで、処理時間を短縮することができます。

プロセス1を開始します
プロセス2を開始します
プロセス3を開始します
全てのプロセスが終了しました

特定のプロセスのみを待機する方法

waitコマンドは、特定のプロセスIDを指定して待機することができます。

これにより、全てのプロセスではなく、特定のプロセスが終了するまで待機することが可能です。

#!/bin/bash
# 複数のバックグラウンドプロセスを実行
sleep 3 &
pid1=$!
sleep 5 &
pid2=$!
# 特定のプロセス (pid1) のみを待機
wait $pid1
# pid1 の終了後にメッセージを表示
echo "プロセス $pid1 が終了しました"
# pid2 の終了を待たずに次の処理を実行

この例では、pid1のプロセスが終了するまで待機し、pid2のプロセスは待機せずに次の処理を進めます。

特定のプロセスのみを待機したい場合に便利です。

プロセス 12345 が終了しました

waitコマンドと他のシェルコマンドの組み合わせ

waitコマンドは、他のシェルコマンドと組み合わせて使うことができます。

例えば、waitコマンドを使ってプロセスの終了を待機し、その後にechogrepなどのコマンドを実行することが可能です。

#!/bin/bash
# バックグラウンドでファイルを作成
echo "ファイルを作成中..." > testfile.txt &
pid=$!
# プロセスの終了を待機
wait $pid
# ファイルの内容を表示
cat testfile.txt

この例では、バックグラウンドでファイルを作成し、そのプロセスが終了するまで待機します。

終了後にcatコマンドでファイルの内容を表示します。

ファイルを作成中...

waitコマンドを使ったエラーハンドリング

waitコマンドは、待機したプロセスの終了ステータスを返すため、エラーハンドリングにも利用できます。

プロセスが正常に終了したかどうかを確認し、エラーが発生した場合に適切な処理を行うことが可能です。

#!/bin/bash
# バックグラウンドでエラーを発生させるプロセスを実行
false &
pid=$!
# プロセスの終了を待機
wait $pid
# 終了ステータスを確認
if [ $? -ne 0 ]; then
  echo "プロセス $pid はエラーで終了しました"
else
  echo "プロセス $pid は正常に終了しました"
fi

この例では、falseコマンドをバックグラウンドで実行し、意図的にエラーを発生させます。

waitコマンドでそのプロセスの終了を待機し、終了ステータスを確認してエラーメッセージを表示します。

プロセス 12345 はエラーで終了しました

waitコマンドの注意点

waitコマンドは非常に便利ですが、使用する際にはいくつかの注意点があります。

ここでは、waitコマンドを使う際に気をつけるべきポイントを解説します。

waitコマンドが無限に待機する場合の対処法

waitコマンドは、指定したプロセスが終了するまで待機しますが、場合によってはプロセスが終了しない、または終了が遅れることがあります。

このような場合、waitコマンドが無限に待機してしまうことがあります。

対処法としては、以下の方法が考えられます。

  • タイムアウトを設定する: timeoutコマンドを使って、指定した時間内にプロセスが終了しない場合に強制的に終了させることができます。
# 10秒以内にプロセスが終了しない場合、強制終了
timeout 10s wait $pid
  • シグナルを送る: killコマンドを使って、プロセスにシグナルを送信し、強制的に終了させることができます。
# プロセスにシグナルを送信して終了させる
kill -9 $pid

これらの方法を使うことで、waitコマンドが無限に待機する状況を回避できます。

プロセスが存在しない場合の挙動

waitコマンドに指定したプロセスIDが存在しない場合、waitコマンドはすぐに終了し、終了ステータスとして127を返します。

これは、指定したプロセスが既に終了しているか、存在しないことを示しています。

# 存在しないプロセスIDを指定
wait 99999
# 終了ステータスを確認
echo $?
127

このように、存在しないプロセスIDを指定した場合、waitコマンドはエラーとして127を返します。

これを利用して、プロセスが存在しない場合のエラーハンドリングを行うことができます。

waitコマンドとシグナルの関係

waitコマンドは、シグナルを受け取るとその動作が中断されることがあります。

例えば、SIGINT(Ctrl+C)やSIGTERMなどのシグナルが送信されると、waitコマンドはそのシグナルを受け取って終了します。

シグナルを無視したい場合は、trapコマンドを使って特定のシグナルを無視するように設定することができます。

#!/bin/bash
# SIGINT (Ctrl+C) を無視する
trap '' SIGINT
# バックグラウンドプロセスを実行
sleep 10 &
pid=$!
# プロセスの終了を待機
wait $pid
# 終了メッセージを表示
echo "プロセス $pid が終了しました"

この例では、trap '' SIGINTを使ってSIGINTシグナルを無視するように設定しています。

これにより、Ctrl+Cを押してもwaitコマンドが中断されず、プロセスの終了を待機し続けます。

シグナルを適切に処理することで、waitコマンドの動作を制御し、予期しない中断を防ぐことができます。

よくある質問

waitコマンドはどのような場合に使うべきですか?

waitコマンドは、主に以下のような場合に使用されます。

  • バックグラウンドプロセスの終了を待機したいとき: 複数のプロセスを並行して実行し、それらが全て終了するまで次の処理を待機したい場合に便利です。
  • シェルスクリプトで並列処理を行うとき: 複数のタスクを並行して実行し、全てのタスクが完了した後に次の処理を行いたい場合に使用します。
  • プロセスの終了ステータスを確認したいとき: waitコマンドは、プロセスの終了ステータスを返すため、プロセスが正常に終了したかどうかを確認する際に役立ちます。

waitコマンドで特定のプロセスが終了しない場合、どうすればいいですか?

特定のプロセスが終了しない場合、以下の対処法があります。

  • タイムアウトを設定する: timeoutコマンドを使って、指定した時間内にプロセスが終了しない場合に強制的に終了させることができます。

例:timeout 10s wait $pid

  • シグナルを送信して強制終了する: killコマンドを使って、プロセスにシグナルを送信し、強制的に終了させることができます。

例:kill -9 $pid

  • プロセスの状態を確認する: psコマンドなどを使って、プロセスが正常に動作しているか確認し、必要に応じて手動で対処します。

waitコマンドはバックグラウンドプロセス以外でも使えますか?

waitコマンドは、基本的にはバックグラウンドプロセスを待機するために使用されますが、フォアグラウンドプロセスには直接使用できません。

フォアグラウンドプロセスは、シェルがそのプロセスの終了を自動的に待機するため、waitコマンドを使う必要がありません。

ただし、バックグラウンドプロセスとして実行されたプロセスや、&を使って明示的にバックグラウンドで実行されたプロセスに対しては、waitコマンドを使用して待機することができます。

まとめ

この記事では、Bashのwaitコマンドについて、その基本的な使い方から応用的な活用方法までを詳しく解説しました。

waitコマンドは、バックグラウンドプロセスの管理や並列処理の制御において非常に有用であり、シェルスクリプトの効率化に役立つツールです。

これを機に、シェルスクリプトでの並列処理やプロセス管理にwaitコマンドを積極的に取り入れてみてください。

  • URLをコピーしました!
目次から探す