バッチファイルで処理を終了するとき、EXIT と EXIT /B はまったく異なる動作をします。「/B を付けるとウィンドウが閉じない」「0 は成功、1 はエラー」という基本から、戻り値の設計・ERRORLEVEL の受け取り方・タスクスケジューラ連携まで、EXIT /B のすべてを体系的に解説します。
EXITとEXIT /Bの違い(ウィンドウが閉じない理由)EXIT /B 0(成功)とEXIT /B 1(失敗)の慣習と使い分け- ERRORLEVEL の正しい受け取り方(比較の落とし穴)
- 戻り値を活用したサブルーチン・別バッチ呼び出しの設計
- タスクスケジューラ・CI/CD との連携パターン
- 負の値・特殊ケースと注意点
EXIT /B とは? /B オプションの意味
EXIT /B の /B は 「Batch(バッチ)の現在のコンテキストだけ終了する」 オプションです。
| コマンド | 動作 | ウィンドウ | 呼び出し元 |
|---|---|---|---|
EXIT |
cmd.exe プロセス自体を終了 | 閉じる | 戻らない |
EXIT /B |
現在のバッチ/サブルーチンを終了 | 閉じない | 戻る |
EXIT /B 0 |
同上 + 戻り値に 0 をセット | 閉じない | 戻る |
EXIT /B 1 |
同上 + 戻り値に 1 をセット | 閉じない | 戻る |
コマンドプロンプトを手動で開いて
.bat を実行した場合、EXIT(/B なし)は cmd.exe ごと終了するためウィンドウが消えます。EXIT /B ならバッチスクリプト内のコンテキストだけを抜けるため、ウィンドウはそのまま残ります。スケジューラから呼ぶ場合も /B を付けることで、プロセスが正常に終了コードを親プロセスに返せます。
EXIT /B の構文
EXIT [/B] [exitCode]
| パラメータ | 省略時の動作 | 指定時の動作 |
|---|---|---|
/B |
cmd.exe プロセスを終了 | 現在のバッチコンテキストのみ終了 |
exitCode |
直前コマンドの ERRORLEVEL を引き継ぐ | 指定した整数値を ERRORLEVEL にセット |
EXIT /B(数値なし)は直前コマンドの ERRORLEVEL をそのまま返します。意図せずエラーコードを伝播させたくない場合は 必ず
EXIT /B 0 や EXIT /B 1 と明示してください。
EXIT /B 0 と EXIT /B 1 の意味(戻り値の慣習)
戻り値(終了コード)には以下の慣習があります。これは Windows のシステムコマンドや多くのプログラムが従う標準です。
| 値 | 意味 | 用途例 |
|---|---|---|
0 |
正常終了(成功) | 処理が問題なく完了した |
1 |
一般エラー | 何か失敗した(理由は問わない簡易エラー) |
2 |
コマンドミス・引数不正 | 使い方が間違っている |
3〜9 |
カスタムエラー | 自前バッチの独自エラー区分に使う |
10〜127 |
アプリ定義エラー | ツール独自の詳細エラーコード |
128〜255 |
プロセス異常終了系 | シグナル終了(バッチでは稀) |
@echo off setlocal :: 成功パターン CALL :Process if %ERRORLEVEL% EQU 0 ( echo 処理成功 ) else ( echo 処理失敗(コード: %ERRORLEVEL%) ) GOTO :EOF :Process xcopy /Y "source*" "dest" >nul 2>&1 if %ERRORLEVEL% NEQ 0 EXIT /B 1 EXIT /B 0
ERRORLEVEL で戻り値を受け取る
EXIT /B N でセットした値は呼び出し元で %ERRORLEVEL% または IF ERRORLEVEL で受け取れます。
方法1:%ERRORLEVEL% 変数で比較(推奨)
CALL :MyFunc if %ERRORLEVEL% EQU 0 echo 成功 if %ERRORLEVEL% EQU 1 echo 失敗 if %ERRORLEVEL% EQU 2 echo 引数エラー
方法2:IF ERRORLEVEL N(旧構文・注意が必要)
CALL :MyFunc IF ERRORLEVEL 2 echo 2以上 IF ERRORLEVEL 1 echo 1以上(2以上も含む!) IF ERRORLEVEL 0 echo 0以上(常に真!)
IF ERRORLEVEL 1 は「ERRORLEVEL が 1 以上」を意味します。EQU 1(ちょうど1)ではありません。複数コードを区別する場合は 大きい値から順に判定するか、
%ERRORLEVEL% EQU N 形式を使ってください。
方法3:ERRORLEVEL を変数に退避してから比較(最安全)
CALL の直後に別コマンドを挟むと ERRORLEVEL が上書きされます。安全のため変数に退避しましょう。
CALL :MyFunc set RC=%ERRORLEVEL% :: echo などのコマンドが ERRORLEVEL を変更しても RC は保持される echo 戻り値: %RC% if %RC% EQU 0 echo 成功処理 if %RC% NEQ 0 echo エラー処理(code=%RC%)
EXIT /B と GOTO :EOF の違い
どちらも「現在のコンテキストを終了して戻る」命令ですが、動作に微妙な差があります。
| 命令 | ERRORLEVEL | SETLOCAL との相性 | 推奨度 |
|---|---|---|---|
EXIT /B 0 |
0 を明示セット | ENDLOCAL を自動実行 | ★★★ 最推奨 |
EXIT /B |
直前の値を引き継ぎ | ENDLOCAL を自動実行 | ★★☆ 省略可だが明示推奨 |
GOTO :EOF |
変更しない | ENDLOCAL を自動実行 | ★★☆ 旧来の書き方 |
戻り値を活用した設計パターン
パターン1:成否だけを返す(0/1)
最もシンプルな設計。成功=0・失敗=1 のみ。
:CopyFiles xcopy /Y "%~1" "%~2" >nul 2>&1 if %ERRORLEVEL% NEQ 0 EXIT /B 1 EXIT /B 0
パターン2:複数の失敗理由を区別する(0/1/2/3)
処理の失敗原因を呼び出し元が判断できるよう、コードを細分化します。
:BackupFile :: 引数チェック if "%~1"=="" EXIT /B 2 :: ファイル存在チェック if not exist "%~1" EXIT /B 3 :: バックアップ実行 copy "%~1" "%~1.bak" >nul 2>&1 if %ERRORLEVEL% NEQ 0 EXIT /B 1 EXIT /B 0 :: 呼び出し側 CALL :BackupFile "C:datalog.txt" set RC=%ERRORLEVEL% if %RC% EQU 0 echo バックアップ成功 if %RC% EQU 1 echo コピー失敗 if %RC% EQU 2 echo 引数が未指定 if %RC% EQU 3 echo ファイルが見つからない
パターン3:別バッチを CALL して戻り値を受け取る
サブルーチンだけでなく、別ファイルのバッチを CALL したときも同様に戻り値を受け取れます。
process.bat(CALL なし直接実行)や START process.bat では ERRORLEVEL が親バッチに返ってきません。必ず
CALL process.bat の形で呼び出してください。
:: main.bat @echo off CALL process.bat set RC=%ERRORLEVEL% if %RC% NEQ 0 ( echo process.bat が失敗しました(code: %RC%) EXIT /B 1 ) echo 全処理完了 EXIT /B 0
:: process.bat @echo off echo 処理中... :: 何らかの理由で失敗 EXIT /B 1
負の値・特殊ケース
EXIT /B に負の値を渡すと?
EXIT /B に負の値を渡すと、ERRORLEVEL には 符号なし 32bit 整数として格納されます。
EXIT /B -1 :: → ERRORLEVEL = 4294967295 (0xFFFFFFFF) EXIT /B -2 :: → ERRORLEVEL = 4294967294
if %ERRORLEVEL% EQU -1 では判定できません(変数には正の値が格納されるため)。IF ERRORLEVEL 1 は 4294967295 でも通るため、一見エラー扱いになりますが、値の比較には使えません。終了コードは 0〜9 の範囲に収めるのが実務的なベストプラクティスです。
タスクスケジューラ・CI/CD との連携
バッチファイルを定期実行する場合、EXIT /B で返した終了コードが外部ツールに伝わります。
タスクスケジューラ
:: backup.bat の最後 if %ERRORLEVEL% NEQ 0 EXIT /B 1 EXIT /B 0
タスクスケジューラでは「最後の実行結果」に終了コードが表示されます。0 以外はエラー扱いになり、アラート設定が可能です。
Jenkins・GitHub Actions など CI/CD
:: Jenkins で bat ステップとして実行する場合 @echo off CALL build.bat if %ERRORLEVEL% NEQ 0 ( echo BUILD FAILED EXIT /B 1 ) echo BUILD SUCCESS EXIT /B 0
CI ツールはプロセスの終了コードが 0 以外の場合にビルドを「失敗」として扱います。EXIT /B 0 を書き忘れると、直前コマンドの ERRORLEVEL によって誤って失敗扱いになるケースに注意してください。
よくあるハマりポイント一覧
| 症状 | 原因 | 解決策 |
|---|---|---|
| ウィンドウが突然閉じる | EXIT(/B なし)を使っている |
EXIT /B に変更する |
| 戻り値が常に 0 以外になる | EXIT /B の直前に失敗コマンドがある |
明示的に EXIT /B 0 と書く |
| IF ERRORLEVEL 1 が常に真になる | IF ERRORLEVEL N は「N以上」の判定 |
if %ERRORLEVEL% EQU 1 を使う |
| CALL直後のERRORLEVELが変わる | echo などのコマンドが ERRORLEVEL を上書き | CALL 直後に set RC=%ERRORLEVEL% で退避 |
| 別バッチの戻り値が取れない | CALL せず直接実行・START で起動している |
CALL process.bat で呼び出す |
| マイナス値を返したが判定できない | 負の値は符号なし整数に変換される | 0以上の値のみ使用する |
よくある質問(FAQ)
❓ EXIT /B 0 と EXIT /B の違いは? (クリックで開閉)
EXIT /B 0 は ERRORLEVEL を明示的に 0(成功)にセットして終了します。
EXIT /B(数値なし)は直前のコマンドの ERRORLEVEL をそのまま引き継ぎます。直前に失敗したコマンドがあると、意図せず非ゼロの ERRORLEVEL が返ってしまうため、明示的に 0 を指定する方が安全です。
❓ バッチ実行後もウィンドウを残すには? (クリックで開閉)
バッチの末尾に PAUSE を入れるのが最も一般的です。
@echo off echo 処理完了 PAUSE EXIT /B 0
または、コマンドプロンプトから cmd /k mybatch.bat で起動すると、バッチ終了後もウィンドウが残ります。
cmd /k "C:scriptsmybatch.bat"
スケジューラや自動化では PAUSE は使えないため、その場合はウィンドウを残す必要自体がありません。
❓ GOTO :EOF と EXIT /B はどちらを使えばよい? (クリックで開閉)
機能はほぼ同等ですが、戻り値を明示したい場合は EXIT /B N 一択です。GOTO :EOF は ERRORLEVEL を変更しません。
新規に書くバッチでは EXIT /B 0 / EXIT /B 1 を統一して使う方がコードの意図が明確になります。
❓ EXIT /B はどこでも使える? (クリックで開閉)
使える場所によって動作が異なります。
- メインバッチの末尾:バッチファイル全体を終了し、呼び出し元(タスクスケジューラ等)に ERRORLEVEL を返す
- CALL :サブルーチン 内:そのサブルーチンを終了して CALL 元に戻る
- CALL で呼んだ別バッチ内:そのバッチを終了して呼び出し元の CALL 行に戻る
いずれも cmd.exe ウィンドウは閉じません(/B の効果)。
まとめ
| 用途 | 書き方 | ポイント |
|---|---|---|
| 正常終了(成功) | EXIT /B 0 |
必ず 0 を明示。省略しない |
| エラー終了 | EXIT /B 1(〜9) |
複数理由は 2・3 と区別 |
| ウィンドウを閉じない | EXIT /B(/Bあり) |
EXIT(/Bなし)は cmd.exe ごと終了 |
| 戻り値の受け取り | set RC=%ERRORLEVEL% |
CALL 直後に変数退避が安全 |
| 戻り値の条件分岐 | if %RC% EQU N |
IF ERRORLEVEL N は「N以上」なので注意 |
| バッチ終了後もウィンドウを残す | PAUSE または cmd /k |
スケジューラ実行時は不要 |
| タスクスケジューラ・CI連携 | 最後に必ず EXIT /B 0/1 |
0=成功 で結果が記録される |
EXIT /B は「ウィンドウを閉じずにコードを返す」というシンプルな命令ですが、数値の有無・ERRORLEVEL の比較方法・負の値の罠・CALL の有無など、正確に使いこなすには細かい知識が必要です。今回解説したパターンを参考に、戻り値を活用した堅牢なバッチファイルを作成してください。

