エラーレベル
にメンテナンス済み
バッチファイルで複数のコマンドを実行する際、「前のコマンドが失敗したら以降の処理を中止したい」「エラーの内容に応じて処理を切り替えたい」といったニーズは頻繁に発生します。
Windows のコマンドプロンプトでは、各コマンドの実行結果を ERRORLEVEL(終了コード)として取得できます。この値を利用することで、バッチファイルにエラーハンドリングを組み込むことができます。
ERRORLEVEL とは
ERRORLEVEL は、直前に実行されたコマンドの終了コード(戻り値)を保持する特殊な変数です。
| 値 | 意味 |
|---|---|
| 0 | 正常終了(成功) |
| 1以上 | エラー(異常終了) |
ERRORLEVEL の値について
多くのコマンドは成功時に 0、失敗時に 1
を返しますが、コマンドによっては異なる値を返す場合があります。例えば ROBOCOPY は 0〜3
が正常、8 以上がエラーです。
ERRORLEVEL を確認する方法
方法 1: %ERRORLEVEL% で参照
copy "source.txt" "dest.txt"
echo 終了コード: %ERRORLEVEL%
方法 2: IF ERRORLEVEL N で判定
copy "source.txt" "dest.txt"
IF ERRORLEVEL 1 (
echo エラーが発生しました。
)
IF ERRORLEVEL の注意点
IF ERRORLEVEL N は「ERRORLEVEL の値が N 以上」の場合に真となります。値が N
と等しいときだけ判定したい場合は IF %ERRORLEVEL% EQU N を使用してください。
方法 3: && と || による簡易判定
成功時と失敗時で処理を分岐
copy "source.txt" "dest.txt" && echo 成功 || echo 失敗
| 演算子 | 意味 |
|---|---|
&& | 直前のコマンドが成功(ERRORLEVEL=0)した場合に実行 |
|| | 直前のコマンドが失敗(ERRORLEVEL≠0)した場合に実行 |
基本的なエラーハンドリング
コマンドの成功・失敗を確認
basic_error.cmd
@echo off
setlocal
copy "important.txt" "backup\important.txt" >nul 2>&1
IF %ERRORLEVEL% EQU 0 (
echo コピーが正常に完了しました。
) ELSE (
echo エラー: コピーに失敗しました。(エラーコード: %ERRORLEVEL%)
)
endlocal
エラー時に処理を中止
abort_on_error.cmd
@echo off
setlocal
echo ステップ1: ファイルをコピーしています...
copy "data.txt" "backup\data.txt" >nul 2>&1
IF %ERRORLEVEL% NEQ 0 (
echo エラー: ステップ1で失敗しました。
GOTO :EOF
)
echo ステップ2: 古いファイルを削除しています...
del "temp\*.tmp" >nul 2>&1
IF %ERRORLEVEL% NEQ 0 (
echo エラー: ステップ2で失敗しました。
GOTO :EOF
)
echo すべての処理が正常に完了しました。
endlocal
カスタム終了コードを設定する
EXIT /B コマンドに数値を付けて、バッチファイル自身の終了コードを設定できます。
custom_exit.cmd
@echo off
setlocal
IF NOT EXIST "config.ini" (
echo エラー: 設定ファイルが見つかりません。
EXIT /B 1
)
IF NOT EXIST "data\" (
echo エラー: データフォルダが見つかりません。
EXIT /B 2
)
echo 処理を開始します。
rem 処理内容...
echo 処理が完了しました。
EXIT /B 0
呼び出し側では、戻り値に応じて処理を分岐できます。
caller.cmd
@echo off
call custom_exit.cmd
IF %ERRORLEVEL% EQU 1 echo 設定ファイルがありません。
IF %ERRORLEVEL% EQU 2 echo データフォルダがありません。
IF %ERRORLEVEL% EQU 0 echo 正常に完了しました。
サブルーチンの終了コード
CALL :ラベル で呼び出したサブルーチンからも終了コードを返すことができます。
subroutine_error.cmd
@echo off
setlocal
CALL :CHECK_FILE "config.ini"
IF %ERRORLEVEL% NEQ 0 (
echo 前提条件を満たしていません。処理を中止します。
GOTO :EOF
)
echo 処理を開始します。
GOTO :EOF
:CHECK_FILE
IF NOT EXIST "%~1" (
echo エラー: %~1 が見つかりません。
EXIT /B 1
)
echo OK: %~1 が見つかりました。
EXIT /B 0
実践例:ログ付きエラーハンドリング
robust_batch.cmd
@echo off
setlocal
set LOGFILE=C:\Logs\batch_%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%.log
CALL :LOG "処理を開始します。"
copy "source\data.csv" "dest\data.csv" >nul 2>&1
IF %ERRORLEVEL% NEQ 0 (
CALL :LOG "エラー: data.csv のコピーに失敗しました。"
GOTO END
)
CALL :LOG "data.csv のコピーが完了しました。"
copy "source\config.ini" "dest\config.ini" >nul 2>&1
IF %ERRORLEVEL% NEQ 0 (
CALL :LOG "エラー: config.ini のコピーに失敗しました。"
GOTO END
)
CALL :LOG "config.ini のコピーが完了しました。"
CALL :LOG "すべての処理が正常に完了しました。"
:END
endlocal
GOTO :EOF
:LOG
echo %DATE% %TIME% - %~1
echo %DATE% %TIME% - %~1 >> "%LOGFILE%"
EXIT /B
チェック
実運用のバッチファイルでは、各ステップの結果をログファイルに記録しておくと、問題発生時の原因特定が容易になります。
よく使うコマンドの終了コード
| コマンド | 成功時 | 失敗時 |
|---|---|---|
copy | 0 | 1 |
xcopy | 0 | 1〜5 |
robocopy | 0〜3 | 8〜16 |
del | 0 | 1 |
find | 0 | 1(文字列が見つからない) |
ping | 0 | 1(応答なし) |
まとめ
| 操作 | 方法 |
|---|---|
| 終了コードを確認 | %ERRORLEVEL% |
| 成功・失敗で分岐 | IF %ERRORLEVEL% EQU 0 |
| N 以上で判定 | IF ERRORLEVEL N |
| 簡易判定 | コマンド && 成功時 || 失敗時 |
| カスタム終了コードを返す | EXIT /B 終了コード |
関連記事
練習問題
#コマンドプロンプト
#バッチファイル
#ERRORLEVEL
#エラーハンドリング
#コマンド