はじめに

こんにちは!今回はwaitコマンドについて解説します。

waitは、バックグラウンドジョブが完了するまで待つコマンドです。複数のタスクを並列実行して、すべての完了を待つ必要がある時に便利ですね。

シェルスクリプトで複数の処理を同時実行して、完了を確認したい時には欠かせませんよ!


waitコマンドとは

waitは、シェルに組み込まれたコマンドで、指定したバックグラウンドプロセスが終了するまで待機します。

複数のプロセスを並列実行する時、すべてが完了するまで次の処理に進みたくない場合があります。そんな時にwaitを使うと、指定したプロセスの終了を待ってから処理を続行できます。

シェルスクリプトでの並列処理制御に重宝します。


基本構文

1
wait [プロセスID または ジョブID]
  • プロセスID/ジョブID指定しない場合、すべてのバックグラウンドプロセスの終了を待つ
  • 複数指定可能

主なオプション

オプション 説明
なし すべてのバックグラウンドプロセス待機
PID 特定のプロセスID待機
%n 特定のジョブID待機
-n 次のプロセス完了まで待機(新しいバージョン)
-p PID 特定のプロセスのみ待機(新しいバージョン)

使用例

例1: すべてのバックグラウンドジョブを待つ

1
2
3
4
sleep 100 &
sleep 200 &
wait
echo "All tasks completed"

実行結果:

1
All tasks completed

すべてのバックグラウンドプロセスが終了するまで待ちます。

例2: 特定のプロセスを待つ

1
2
3
4
5
sleep 100 &
PID=$!
sleep 50
wait $PID
echo "Process $PID completed"

実行結果:

1
Process 12345 completed

特定のプロセスIDの終了を待ちます。

例3: ジョブIDで待つ

1
2
3
4
sleep 100 &
sleep 200 &
wait %1
echo "Job 1 completed"

実行結果:

1
Job 1 completed

ジョブ1が完了すると、メッセージが表示されます。

例4: 複数のプロセスを待つ

1
2
3
4
5
long_task1 &
long_task2 &
long_task3 &
wait
echo "All long tasks completed"

実行結果:

1
All long tasks completed

3つのタスクがすべて終了するまで待ちます。

例5: 最後のプロセスを待つ

1
2
3
4
5
sleep 50 &
sleep 100 &
sleep 30 &
wait
echo "最も時間がかかったタスクが完了"

実行結果:

1
最も時間がかかったタスクが完了

100秒後にメッセージが表示されます。

例6: シェルスクリプトでの並列処理

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#!/bin/bash
process_file() {
  echo "Processing $1"
  sleep 5
}

process_file file1.txt &
process_file file2.txt &
process_file file3.txt &

wait
echo "All files processed"

実行結果:

1
2
3
4
Processing file1.txt
Processing file2.txt
Processing file3.txt
All files processed

複数ファイルの処理を並列実行して、すべての完了を待ちます。

例7: エラー処理を含む待機

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
task1 &
PID1=$!
task2 &
PID2=$!

wait $PID1
echo "Task1 exit code: $?"

wait $PID2
echo "Task2 exit code: $?"

実行結果:

1
2
Task1 exit code: 0
Task2 exit code: 0

各プロセスの終了コードを確認できます。

例8: タイムアウト付きで待つ

1
2
3
4
5
6
7
sleep 100 &
PID=$!

( sleep 10 && kill $PID 2>/dev/null ) &

wait $PID
echo "Process completed or timed out"

実行結果:

1
Process completed or timed out

10秒でタイムアウトさせることができます。

例9: バックグラウンドジョブの監視

1
2
3
4
5
6
for i in {1..5}; do
  ./process_task.sh &
done

wait
echo "All 5 tasks completed"

実行結果:

1
All 5 tasks completed

ループで複数のジョブを実行して、すべての完了を待ちます。

例10: 終了コードの確認

1
2
3
4
5
6
success_task &
fail_task &

wait
echo "Both tasks completed"
echo "Exit status: $?"

実行結果:

1
2
Both tasks completed
Exit status: 1

最後のプロセスの終了コードが返されます。


Tips・注意点

$! で最後のプロセスIDを取得

1
2
3
long_task &
PID=$!
wait $PID

$!で最後に実行したバックグラウンドプロセスのIDを取得できます。

複数プロセスの終了コード確認

1
2
3
4
5
6
task1 &
task2 &
task3 &

wait
RESULT=$?

waitの戻り値は最後に終了したプロセスの終了コードです。

waitは非同期待機ではない

1
2
3
4
# waitは同期的に待つ
wait $PID    # ここで処理が止まる

# 非同期に待ちたい場合は別の手法が必要

waitコマンドはプロセスが終了するまで処理が進みません。

シェルスクリプトでの活用

1
2
3
4
5
6
7
8
#!/bin/bash
for file in *.csv; do
  process_csv "$file" &
done

wait
echo "All CSV files processed"
echo "Ready for next step"

スクリプトで並列処理と順序処理を組み合わせられます。


実践的な使い方

複数ファイルの並列ダウンロード

1
2
3
4
5
6
7
8
#!/bin/bash
for url in ${URLS[@]}; do
  wget "$url" &
done

wait
echo "All files downloaded"
tar czf archive.tar.gz *.zip

複数ファイルを同時ダウンロードしてから圧縮します。

バッチ処理の完了待ち

1
2
3
4
5
6
7
8
#!/bin/bash
for i in {1..10}; do
  ./batch_process.sh $i &
done

wait
echo "All batch processes completed"
./generate_report.sh

10個のバッチプロセスが完了してからレポートを生成します。

並列テストの実行

1
2
3
4
5
6
7
#!/bin/bash
python -m pytest test_suite1.py &
python -m pytest test_suite2.py &
python -m pytest test_suite3.py &

wait
echo "All test suites completed"

複数のテストスイートを並列実行してから、結果をまとめます。


まとめ

waitコマンドのポイント:

  • バックグラウンドプロセスの終了を待機
  • シェルの組み込みコマンド
  • 基本形: command & wait
  • 複数プロセスの終了待機に便利
  • 終了コードで完了状況を確認可能
  • シェルスクリプトでの並列処理制御に重要
  • よく使う組み合わせ: command & ; wait $!

複数のタスクを並列実行してから進行するシェルスクリプトに欠かせないコマンド。効率的なバッチ処理やテスト実行に重宝しますよ!