Bash wait コマンドの例

Bash の wait コマンドは、シェル スクリプト プロセスを管理するための強力なツールです。このコマンドは主に、指定されたバックグラウンド プロセスが終了するまでスクリプトの実行を一時停止するために使用されます。このコマンドは、複数のバックグラウンド ジョブを開始し、それらの完了を同期してから次のタスクに進む必要があるスクリプトで便利です。wait コマンドは、個々のプロセス ID (PID) に適用することも、現在のシェル セッションによって開始されたすべてのバックグラウンド プロセスを待機することもできます。wait を使用すると、特定のタスクが完全に完了したときにのみスクリプトが進むようにすることができ、自動化プロセスの信頼性と効率が向上します。

このガイドでは、さまざまなシナリオで wait コマンドを使用する実用的な例を示し、Bash スクリプトでバックグラウンド プロセスを効果的に管理する方法を理解するのに役立ちます。

Bash wait コマンドを理解する

Bash の wait コマンドは、指定されたジョブが完了するまで現在のシェルの実行を停止する組み込み関数です。その後、待機していたコマンドの終了ステータスを返します。このコマンドはシェル実行環境で重要な役割を果たしているため、ほとんどのシェルに組み込まれています。

wait コマンドの一般的な構文は次のとおりです。

wait [ID]

このコンテキストでは、ID はプロセスまたはジョブ ID を表します。ID が指定されていない場合、wait コマンドはすべての子バックグラウンド ジョブが終了するまで一時停止します。wait コマンドは、待機していた最後のコマンドの終了ステータスを返します。

たとえば、PID 7654 のバックグラウンド プロセスを一時停止するには、次のようにします。

wait 7654

複数のプロセスが指定されている場合、wait コマンドはそれらが完了するまで一時停止します。

bash wait コマンドでジョブ仕様をナビゲートする

ジョブは、ジョブを構成するプロセスを参照するジョブ仕様 (jobspec) を使用して指定されます。jobspec は、パーセント記号で始まり、その後にジョブ番号 (%n) が続きます。次に例を示します。

rsync -a /home /tmp/home &

このコマンドはバックグラウンドで実行されます。シェル ジョブ ID (括弧で囲まれている) とプロセス ID が端末に表示されます。ジョブを一時停止するには、wait コマンドに続いてジョブ仕様を実行します。

wait %2

bash wait コマンドで -n オプションを使用する

-n オプションを使用すると、wait コマンドは指定された PID またはジョブ仕様の 1 つのジョブが完了するまで一時停止し、その終了ステータスを返します。引数が指定されていない場合、wait -n はバックグラウンド ジョブが完了するまで待機し、ジョブの終了ステータスを返します。

wait -n 45432 54346 76573

上記の例では、wait -nは最初に終了したジョブの戻りステータスのみを出力します。ジョブのPIDは表示されません。終了ステータスが返されるジョブPIDまたはジョブ仕様を取得したい場合は、 -p 変数に割り当てるオプション:

wait -p job_id -n 45432 54346 76573

-p オプションは Bash 5.1 で導入されました。古いバージョンの Bash を使用すると、「無効なオプション」エラーが発生します。

bash wait コマンドの -f オプションを調べる

-f オプションは、ジョブ ステータスが変更されたときに戻るのではなく、各 PID またはジョブ仕様が終了するまで待機して、終了コードを返すように指示します。このオプションは、ジョブ制御が有効な場合にのみ有効です。ジョブ制御は、デフォルトでは対話型プロンプトに対してのみ有効です。

wait コマンドの実例

wait コマンドは通常、並列に実行される子プロセスを生成するシェル スクリプトで使用されます。コマンドの動作を説明するために、次のスクリプトを作成しましょう。

#!/bin/bash
sleep 30 &
process_id=$!
echo "PID: $process_id"
wait $process_id
echo "Exit status: $?"

コードを行ごとに分解してみましょう。

  • 最初の行の shebang は、ファイルの残りの部分を解析するためにどのインタープリターを使用するかをオペレーティング システムに指示します。
  • 時間のかかるバックグラウンド プロセスをエミュレートするために sleep コマンドを使用しています。
  • $! は、バックグラウンドで最後に実行されたジョブの PID を格納する内部 Bash 変数です。この例では、これは sleep コマンドの PID です。PID を変数 (process_id) に格納しています。
  • PID番号が印刷されます。
  • PID は、スリープ コマンドが完了するまで一時停止する wait コマンドに渡されます。
  • wait コマンドの終了ステータスが出力されます。$? は、最後に実行されたコマンドの終了ステータスを保持する内部 Bash 変数です。

スクリプトを実行すると、次のような出力が表示されます。

PID: 36353
Exit status: 0

-n オプションを使用した例を次に示します。

#!/bin/bash
sleep 3 &
sleep 30 &
sleep 5 &
wait -n
echo "First job completed."
wait
echo "All jobs completed."

スクリプトが実行されると、3 つのバックグラウンド プロセスが生成されます。wait -n は、最初のジョブが完了して echo ステートメントが印刷されるまで一時停止します。wait は、すべての子バックグラウンド ジョブが完了するまで一時停止します。

First job completed.
All jobs completed.

最後の例は -f オプションについて説明しています。ターミナルを開いて次を実行します:

sleep 3600 &
[1] 46671
wait 46671

別のターミナルを開き、kill コマンドでプロセスを停止します。

kill -STOP 46671

プロセスの状態が変化すると、wait コマンドが完了し、プロセス終了コードが返されます。

ここで、同じ手順を繰り返しますが、今回は wait -f $pid を使用します。

sleep 3600 &
wait -f 46671

他のターミナルからプロセスを停止します。

kill -STOP 46671

今回は、wait コマンドは完了しません。スリープ プロセスが終了するまで実行されます。

wait コマンドの高度な使用法

wait コマンドは、スクリプト内で複数のプロセスを管理する場合に特に便利です。これにより、実行フローを制御し、特定のプロセスが他のプロセスの開始前に完了していることを確認できます。これを説明するために、より複雑な例をいくつか見てみましょう。

Bash 複数プロセスを待機する

複数のプロセスがバックグラウンドで実行され、それらのプロセスが完了した後にのみアクションを実行する必要があるシナリオを考えてみましょう。 wait コマンドを使用してこれを実現する方法は次のとおりです。

#!/bin/bash
echo "Starting process 1..."
sleep 10 &
pid1=$!

echo "Starting process 2..."
sleep 15 &
pid2=$!

echo "Starting process 3..."
sleep 20 &
pid3=$!

echo "Waiting for processes to complete..."
wait $pid1 $pid2 $pid3
echo "All processes completed."

このスクリプトは、それぞれ 10、15、20 秒間スリープする 3 つのバックグラウンド プロセスを開始します。各プロセスの PID を変数に格納します。次に、3 つの PID すべてを引数として wait コマンドを使用します。スクリプトは、3 つのプロセスがすべて完了するまで wait コマンドで一時停止します。

ループでBash waitを使用する

また、ループで wait を使用して複数のプロセスを管理することもできます。次に例を示します。

#!/bin/bash
for i in {1..5}
do
   echo "Starting process $i..."
   sleep $i &
   pids[${i}]=$!
done

echo "Waiting for processes to complete..."
for pid in ${pids[*]}; do
    wait $pid
done

echo "All processes completed."

このスクリプトでは、ループ内で 5 つのバックグラウンド プロセスを開始します。各プロセスは、ループ内のインデックスと同じ数秒間スリープします。各プロセスの PID を配列に格納します。すべてのプロセスを開始した後、配列をループし、wait コマンドを使用して各プロセスを個別に一時停止します。スクリプトは、対応するプロセスが完了するまで、各 wait コマンドで一時停止します。

結論

Bash の wait コマンドは、スクリプト内のバックグラウンド プロセスを同期するために不可欠です。wait の使い方を理解することで、スクリプトのフローをより正確に制御し、タスクが目的の順序で完了するようにすることができます。複数のバックグラウンド ジョブを処理する場合でも、続行する前に特定のプロセスが完了することを確実にする必要がある場合でも、wait コマンドを使用すると、より信頼性が高く予測可能なスクリプトの動作を実現できます。プロセス管理を強化し、スクリプト全体の効率を向上させるために、スクリプトに wait を統合することを検討してください。

Joshua James

コメントを残す