【bat】EXIT /B 完全解説|/B オプション・戻り値 0/1・ウィンドウを閉じない仕組みと活用パターン

【bat】EXIT /B 完全解説|/B オプション・戻り値 0/1・ウィンドウを閉じない仕組みと活用パターン bat

バッチファイルで処理を終了するとき、EXITEXIT /B はまったく異なる動作をします。「/B を付けるとウィンドウが閉じない」「0 は成功、1 はエラー」という基本から、戻り値の設計・ERRORLEVEL の受け取り方・タスクスケジューラ連携まで、EXIT /B のすべてを体系的に解説します。

この記事で学べること

  • EXITEXIT /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 にセット
exitCode を省略すると危険なケースがある
EXIT /B(数値なし)は直前コマンドの ERRORLEVEL をそのまま返します。
意図せずエラーコードを伝播させたくない場合は 必ず EXIT /B 0EXIT /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 N は「N 以上」の判定
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 したときも同様に戻り値を受け取れます。

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 の有無など、正確に使いこなすには細かい知識が必要です。今回解説したパターンを参考に、戻り値を活用した堅牢なバッチファイルを作成してください。