「処理の途中で数秒待ってから次のステップに進みたい」「ユーザーに確認を促してから実行したい」「リトライの間に一定時間待機させたい」——バッチファイルの一時停止は目的によって使うコマンドが変わります。本記事では timeout・pause・choice・ping・WScript.Sleep を用途別に解説し、カウントダウン表示・リトライ待機・タイムアウト付き確認プロンプトなど実践パターンまで体系的に説明します。
- 指定した秒数だけ処理を止める方法(
timeout) - キーを押すまで処理を止める方法(
pause) - タイムアウト付きで選択肢を表示して待機する方法(
choice) - ミリ秒単位で待機する方法(
WScript.Sleep) - カウントダウンを画面に表示しながら待機するパターン
- リトライループで一定間隔を空けて再実行するパターン
方法の比較
| コマンド | 単位 | キー中断 | 主な用途 |
|---|---|---|---|
timeout /t N |
秒 | 可(/nobreak で禁止) | 秒単位の待機・定番 |
pause |
— | 任意キー待ち | 確認プロンプト・ユーザー操作待ち |
choice /t N |
秒 | 選択キー | タイムアウト付き Yes/No 確認 |
ping -n N+1 127.0.0.1 |
秒 | Ctrl+C | timeout 非対応の旧環境 |
WScript.Sleep N |
ミリ秒 | Ctrl+C | ミリ秒単位の精密な待機 |
方法1: timeout コマンド(秒単位・定番)
基本: 指定秒数だけ待機
@echo off echo 処理を5秒間停止します... timeout /t 5 echo 再開しました
実行するとカウントダウンが表示され、5秒後に自動で次の処理に進みます。
カウントダウン中に Enter や任意のキーを押すと即座にスキップできます。
キー入力によるスキップを禁止する(/nobreak)
@echo off echo 重要な処理を実行中... 10秒間キーを押しても中断できません timeout /t 10 /nobreak echo 待機完了
/nobreak を付けると キー入力でスキップできなくなります。
ただし Ctrl+C は /nobreak があっても中断可能です。
カウントダウン表示を非表示にする(>nul)
@echo off echo バックグラウンドで5秒待機中... timeout /t 5 /nobreak >nul echo 完了
>nul を付けるとカウントダウンのメッセージが表示されなくなります。画面をすっきりさせたいときに便利です。
ループ内で定期的に待機する
@echo off
setlocal
set INTERVAL=30
set REPEAT=5
for /l %%I in (1,1,%REPEAT%) do (
echo [%%I/%REPEAT%] 処理実行中... %TIME%
rem ここに繰り返す処理を記述
echo → 次回まで %INTERVAL% 秒待機
timeout /t %INTERVAL% /nobreak >nul
)
echo 全 %REPEAT% 回完了
endlocal
timeout は Windows Vista 以降で使用可能です。Windows XP などの旧環境では ping コマンド を代わりに使用してください。timeout /t 0 と指定するとすぐに次へ進みます(実質スキップ)。
方法2: pause コマンド(任意キー入力待ち)
pause は「続行するには何かキーを押してください…」と表示して、ユーザーがキーを押すまで無制限に待機します。時間指定はできません。
基本: キー入力待ち
@echo off echo 重要ファイルを削除しようとしています echo 続行する場合はキーを押してください pause echo 処理を続行します...
pause のメッセージを日本語に変える
@echo off echo ファイルのバックアップが完了しました echo. echo ■ 続行するには Enter キーを押してください pause >nul echo 次の処理を開始します...
pause >nul とすると「続行するには何かキーを押してください…」の表示が消え、自分のメッセージだけ表示できます。
スクリプト末尾に pause を入れてウィンドウを閉じないようにする
@echo off echo 処理1を実行... echo 処理1完了 echo 処理2を実行... echo 処理2完了 echo. echo 全処理が完了しました pause
ダブルクリックで実行したときにウィンドウがすぐ閉じてしまう問題を防ぐ定番パターンです。
方法3: choice コマンド(タイムアウト付き確認プロンプト)
choice は 指定した選択肢のキーを待ち、タイムアウトすると自動でデフォルト選択肢を選ぶ コマンドです。
基本: Y/N の確認付き待機
@echo off
echo 処理を続行しますか? [Y/N]
choice /c YN /m "続行 [Y] / 中止 [N]"
if errorlevel 2 (
echo 中止しました
exit /b 0
)
echo 処理を続行します...
タイムアウト付き確認(一定時間後に自動で進む)
@echo off
echo 10秒以内に選択してください。何もしなければ自動で [Y] を選びます
rem /t 10 = タイムアウト秒数 /d Y = デフォルト選択
choice /c YN /t 10 /d Y /m "続行 [Y] / 中止 [N]"
if errorlevel 2 (
echo 中止しました
exit /b 0
)
echo 続行します...
choice /c YN の場合、Y を押すと errorlevel=1、N を押すと errorlevel=2 になります。判定は必ず 大きい値から順に
if errorlevel でチェックしてください(小さい値からチェックすると常に最初の条件に引っかかります)。
タイムアウト中にカウントダウンを手動表示
@echo off
setlocal enabledelayedexpansion
echo バックアップを開始します
for /l %%I in (5,-1,1) do (
set /p =%%I 秒後に開始します... <nul
timeout /t 1 /nobreak >nul
echo.
)
echo 開始します!
endlocal
方法4: ping コマンド(旧環境向け)
timeout が使えない Windows XP などの旧環境では、ping のループバックアドレスへの送信を利用して待機します。
基本: ping で N 秒待機
@echo off rem ping の -n は送信回数。1回約1秒かかるため N秒待機 = -n N+1 にする echo 5秒間待機中... ping -n 6 127.0.0.1 >nul echo 完了
ping -n N+1 127.0.0.1 で約 N 秒待機できます。
最初の1回が「即座に送信される」ため、N 秒待機には N+1 回送信する必要があります。
変数で待機秒数を指定
@echo off setlocal enabledelayedexpansion set WAIT=10 set /a PING_COUNT=%WAIT%+1 echo !WAIT! 秒間待機中... ping -n !PING_COUNT! 127.0.0.1 >nul echo 完了 endlocal
方法5: WScript.Sleep(ミリ秒単位の精密待機)
timeout は秒単位ですが、WScript.Sleep を使うと ミリ秒単位 の精密な待機が可能です。VBScript を cscript で呼び出す方法と、一時ファイルを使う方法があります。
インラインで WScript.Sleep を呼び出す
@echo off echo 500ミリ秒(0.5秒)待機... cscript //nologo //e:vbscript "%~f0_.vbs" 500 echo 完了 goto :end rem ※ このスクリプトと同フォルダに sleep.vbs を用意する場合は以下 :end
一時 VBS ファイルを生成してミリ秒待機(推奨)
@echo off setlocal rem 待機ミリ秒数を設定(例: 1500ms = 1.5秒) set WAIT_MS=1500 rem 一時 VBS ファイルを生成 set TMPVBS=%TEMP%\sleep_tmp.vbs echo WScript.Sleep(%WAIT_MS%) > "%TMPVBS%" echo %WAIT_MS%ms 待機中... cscript //nologo "%TMPVBS%" rem 一時ファイルを削除 del /q "%TMPVBS%" echo 完了 endlocal
cscript の起動に数十〜数百ミリ秒かかるため、短時間(100ms 以下)の精密待機には向きません。サブミリ秒精度が必要な場合は PowerShell の
Start-Sleep -Milliseconds を使ってください。
PowerShell でミリ秒待機
@echo off echo 800ミリ秒待機... powershell -NoProfile -Command "Start-Sleep -Milliseconds 800" echo 完了
実践例A: リトライループ(失敗時に一定間隔で再試行)
ネットワーク接続確認など、失敗した場合に間隔を空けて再試行するパターンです。
@echo off
setlocal enabledelayedexpansion
set TARGET=192.168.1.1
set MAX_RETRY=5
set WAIT_SEC=10
for /l %%I in (1,1,%MAX_RETRY%) do (
echo [%%I/%MAX_RETRY%] %TARGET% に接続確認中... %TIME%
ping -n 1 %TARGET% >nul 2>&1
if not errorlevel 1 (
echo [OK] 接続成功
goto :connected
)
echo [FAIL] 接続失敗 - %WAIT_SEC% 秒後に再試行...
timeout /t %WAIT_SEC% /nobreak >nul
)
echo [ERROR] %MAX_RETRY% 回試行しましたが接続できませんでした
exit /b 1
:connected
echo 処理を続行します
endlocal
実践例B: カウントダウン表示付き待機
残り時間をユーザーに視覚的に伝えながら待機するパターンです。
@echo off
setlocal enabledelayedexpansion
set WAIT=10
echo 処理を !WAIT! 秒後に開始します。キャンセルするには Ctrl+C を押してください
echo.
for /l %%I in (!WAIT!,-1,1) do (
echo 残り %%I 秒...
timeout /t 1 /nobreak >nul
)
echo.
echo 処理を開始します!
endlocal
実践例C: タイムアウト付き確認プロンプト(自動続行)
夜間バッチなど無人実行を前提としつつ、手動実行時は確認を取るパターンです。
@echo off
setlocal
echo ========================================
echo 本番データベースのバックアップを開始します
echo ========================================
echo.
echo 15秒以内に [N] を押すとキャンセルします
echo 何もしなければ自動で続行します
echo.
choice /c YN /t 15 /d Y /m "続行 [Y] / キャンセル [N]" >nul
if errorlevel 2 (
echo キャンセルしました
exit /b 0
)
echo バックアップを開始します... %DATE% %TIME%
rem ここにバックアップ処理を記述
echo バックアップ完了
endlocal
よくある落とし穴
落とし穴1: timeout /t 0 で即座に終了(待機しない)
rem timeout /t 0 は待機なしで即座に次の処理へ進む rem (実質 pause なし。0秒待機) timeout /t 0 >nul rem 1秒以上待機したい場合は /t 1 以上を指定する timeout /t 1 >nul
落とし穴2: ping の待機秒数がずれる(-n の計算間違い)
rem NG: -n 5 は 5回送信 → 約4秒しか待機しない(最初の1回が即時) ping -n 5 127.0.0.1 >nul rem OK: N秒待機するには -n N+1 を指定する rem 5秒待機したい場合 ping -n 6 127.0.0.1 >nul
落とし穴3: pause はパイプやリダイレクト先では動作しない
rem NG: スクリプトを別コマンドから呼び出すと pause が即座に終了する場合がある rem 例: echo Y | mybatch.bat ← pause が Y で即応答してしまう rem 確認待ちには choice /c YN を使う方が信頼性が高い choice /c YN /m "続行しますか [Y/N]" if errorlevel 2 exit /b 0
落とし穴4: タスクスケジューラから実行すると pause で処理が止まる
rem タスクスケジューラや CI/CD で実行する場合 rem pause は誰もキーを押せないので処理が永遠に止まる rem 無人実行を前提とするスクリプトでは pause を使わない rem 代わりに timeout /nobreak か choice /t でタイムアウト付きにする timeout /t 5 /nobreak >nul
落とし穴5: choice の errorlevel を小さい値から判定するとバグる
rem NG: errorlevel は指定した値以上で真になるため、小さい値から判定するとバグ choice /c YN if errorlevel 1 echo Y が押された ← N(=2) でも真になってしまう! if errorlevel 2 echo N が押された rem OK: 大きい値から順に判定する choice /c YN if errorlevel 2 echo N が押された if errorlevel 1 echo Y が押された
よくある質問(FAQ)
timeout /nobreak はキー入力をブロックしますが Ctrl+C は防げません。
完全に中断を防ぐ方法は bat 単体では難しいため、重要な処理はタスクスケジューラや PowerShell から制御することを推奨します。
現代の環境(Windows 7 以降)では timeout を使うのが定番です。
ping は Windows XP などの古い環境や、timeout が使えない制限環境向けの代替手段です。
| 項目 | timeout | ping |
|---|---|---|
| 対応 OS | Vista 以降 | 全バージョン |
| カウントダウン表示 | あり(>nul で非表示) | ping 応答が表示される |
| キー中断禁止 | /nobreak で可能 | 不可 |
| 秒数の精度 | 高い | やや不安定 |
timeout の場合は >nul を付けるとカウントダウン全体が非表示になります。
pause の場合は pause >nul とすることで「続行するには何かキーを押してください…」のメッセージを消せます。
rem timeout のカウントダウンを非表示 timeout /t 5 /nobreak >nul rem pause のメッセージを非表示(任意のメッセージと組み合わせる) echo ■ 続行するには何かキーを押してください pause >nul
リトライループと最大試行回数を組み合わせることで、タイムアウトエラーを実装できます。
@echo off
setlocal enabledelayedexpansion
set MAX_RETRY=10
set WAIT=3
for /l %%I in (1,1,%MAX_RETRY%) do (
rem 条件チェック(ここでは例として test.txt の存在確認)
if exist "test.txt" (
echo [OK] 条件を満たしました
goto :success
)
echo [%%I/%MAX_RETRY%] 待機中... %WAIT% 秒後に再確認
timeout /t %WAIT% /nobreak >nul
)
echo [ERROR] タイムアウト: !MAX_RETRY! 回試行しましたが条件を満たしませんでした
exit /b 1
:success
endlocal
timeout と pause を組み合わせたパターンが使えます。
@echo off echo 処理が完了しました echo. echo 10秒後に自動で終了します。今すぐ閉じるには何かキーを押してください timeout /t 10
まとめ
| 目的 | 推奨コマンド |
|---|---|
| N 秒間待機(定番) | timeout /t N /nobreak >nul |
| キーを押すまで待機 | pause(無人実行には不向き) |
| タイムアウト付き確認プロンプト | choice /c YN /t N /d Y |
| 旧環境(XP 等)での待機 | ping -n N+1 127.0.0.1 >nul |
| ミリ秒単位の精密待機 | WScript.Sleep または Start-Sleep -Milliseconds |
| リトライ間隔待機 | timeout + for /l ループ |
| カウントダウン表示 | for /l %%I in (N,-1,1) + timeout /t 1 |
バッチファイルのループ処理については 複数フォルダをループして一括処理する方法 を、ファイル操作については ファイルを別フォルダに移動する方法 も合わせて参照してください。