言語
日本語
English

Caution

お使いのブラウザはJavaScriptが無効になっております。
当サイトでは検索などの処理にJavaScriptを使用しています。
より快適にご利用頂くため、JavaScriptを有効にしたうえで当サイトを閲覧することをお勧めいたします。

  1. トップページ
  2. Bash辞典
  3. wait / trap

wait / trap

『wait』はバックグラウンドプロセスの終了を待ちます。『trap』はシグナルやシェルの終了イベントをキャッチして任意の処理を実行します。スクリプトのクリーンアップ処理や安全な終了処理の実装に欠かせません。

構文

wait でプロセスの待機を行います。

wait           # 全バックグラウンドジョブが終了するまで待つ
wait $PID      # 指定した PID が終了するまで待つ
wait %ジョブ番号  # 指定したジョブが終了するまで待つ

trap でシグナルをキャッチします。

trap '処理' シグナル名...
trap '処理' EXIT     # スクリプト終了時に必ず実行
trap '処理' INT      # Ctrl+C(SIGINT)をキャッチ
trap '処理' TERM     # SIGTERM をキャッチ
trap '処理' ERR      # コマンドがエラーになったときにキャッチ

trap を解除します。

trap - シグナル名    # デフォルト動作に戻す
trap '' シグナル名   # シグナルを無視する

コマンド一覧

コマンド/シグナル概要
wait全バックグラウンドジョブが完了するまで待ちます。
wait $PID指定した PID のプロセスが終了するまで待ちます。終了ステータスを返します。
trap '処理' EXITスクリプトの終了時(正常・異常問わず)に実行されます。一時ファイルの削除に便利です。
trap '処理' INTCtrl+C が押されたときに実行されます。
trap '処理' TERMSIGTERM を受信したときに実行されます。
trap '処理' ERRコマンドが 0 以外の終了ステータスを返したときに実行されます。
trap '処理' HUPSIGHUP を受信したときに実行されます(端末切断・設定再読み込み)。
trap '' INTCtrl+C を無視します(重要な処理中の誤操作防止)。

サンプルコード

『trap ... EXIT』で一時ファイルを確実に削除します。正常終了・エラー終了・Ctrl+C のいずれでもクリーンアップが実行されます。

cleanup.sh
#!/bin/bash
tmpfile=$(mktemp /tmp/myapp.XXXXXX)
echo "一時ファイル: $tmpfile"

trap 'rm -f "$tmpfile"; echo "クリーンアップ完了"' EXIT

echo "処理データ" > "$tmpfile"
cat "$tmpfile"
bash cleanup.sh
一時ファイル: /tmp/myapp.aB3xYz
処理データ
クリーンアップ完了

Ctrl+C(SIGINT)や SIGTERM を捕捉して安全に終了する例です。クリーンアップ処理を関数にしておくと管理しやすくなります。

safe_exit.sh
#!/bin/bash
cleanup() {
    echo ""
    echo "割り込みを検出しました。安全に終了します..."
    exit 0
}
trap cleanup INT TERM

echo "Ctrl+C で終了できます(3秒後に自動終了)"
sleep 3
echo "正常終了"
bash safe_exit.sh
Ctrl+C で終了できます(3秒後に自動終了)
正常終了

『wait』と『trap』を組み合わせた並列処理の例です。複数のワーカーをバックグラウンドで起動し、個別に終了ステータスを確認します。

parallel_worker.sh
#!/bin/bash
worker() {
    local id=$1
    sleep $(( RANDOM % 3 + 1 ))
    echo "ワーカー $id 完了"
    return 0
}

pids=()
for i in {1..3}; do
    worker $i &
    pids+=($!)
done

echo "全ワーカーの完了を待っています..."
for pid in "${pids[@]}"; do
    wait "$pid"
    echo "PID $pid の終了ステータス: $?"
done
echo "全ワーカー完了"
bash parallel_worker.sh
全ワーカーの完了を待っています...
ワーカー 2 完了
ワーカー 3 完了
ワーカー 1 完了
PID 12345 の終了ステータス: 0
PID 12346 の終了ステータス: 0
PID 12347 の終了ステータス: 0
全ワーカー完了

概要

trap ... EXIT』はスクリプトが正常終了・エラー終了・SIGTERM・SIGINT のどの場合でも実行されます(SIGKILL は除く)。一時ファイルの削除・ロックファイルの解除・ログへの書き込みなどクリーンアップ処理の定番パターンです。本番スクリプトには必ず書くことを推奨します。

trap のハンドラを関数にしておくと複数のシグナルに同じ処理を登録でき、後から変更もしやすくなります。

バックグラウンド実行の詳細は &(バックグラウンド実行) を参照してください。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。