
Windowsでバッチファイルを作成していると、バッチファイルやバッチファイル内で実行したコマンドでエラーが発生してかるかに応じて処理を分けたい(エラーハンドリングしたい)ときがあります。
そこでここでは、バッチファイルやバッチファイル内で実行したコマンドが正常終了したか異常終了したかを判別する方法を解説します。
目次
ERRORLEVEL変数を使った判別
Windowsコマンドの多くは、正常にコマンドが実行されると終了コード(Exit Code)として「0」が返され、何らかのエラーが発生したときは0以外の数値が返され、終了コードがERRORLEVELという変数に格納されます。
そこで、エラーハンドリングしたいコマンドを実行するときは、以下のようにコマンドの実行直後にERRORLEVELに格納されている値をIF文などでチェックすることでエラーを判別できます。
rename e:\samaple1.txt test.txt
if %errorlevel% neq 0 (
echo エラーが発生しました
)なお、コマンドによっては正常終了したときでも「0」以外の値を返すことがあります。たとえば、robocopyコマンドでは、実行結果に応じてさまざまな値を返すので、使用するコマンドが正常終了したときや異常終了したときにどのような終了コードを返すのかをあらかじめ確認しておく必要があります。
条件付きの連結演算子による判別
バッチファイルでは、左側のコマンドが正常終了したときに右側のコマンドを実行する演算子として「&&」、左側のコマンドが異常終了したときに右側のコマンドを実行する演算子として「||」が使えます。「||」や「&&」を使えば、if文を使うよりもよりシンプルに正常や異常を判別できます。
たとえば、下のコマンドでは「rename e:\samaple1.txt test.txt」が正常終了したときのみ「echo 処理が成功しました。」が実行されます。
> rename e:\samaple1.txt test.txt && echo 処理が成功しました。下のコマンドでは「rename e:\samaple1.txt test.txt」が異常終了したときのみ「echo エラーが発生しました。」が実行されます。
> rename e:\samaple1.txt test.txt || echo エラーが発生しました。出力メッセージによる判別
コマンドの中には、正常終了しても異常終了しても終了コードを0でしか返さないコマンドがあります。たとえば、ファイルを削除するDELコマンドは、正常にファイルが削除されてもエラーが発生しても終了コードとして0しか返さないため、ERRORLEVELを使ったエラーハンドリングができません。
そのようなときは、別の手段を考える必要があります。
たとえば、DELコマンドなら、エラーが発生したときのみ標準エラー出力にファイルを削除できなかったなどのメッセージが出力されるため、FINDコマンドと組み合わせてメッセージの有無をチェックすることでエラーを判別できます。
del a.txt 2>&1 | find /v ""
if %errorlevel% neq 1 (
echo エラーが発生しました
)上のコマンドでは、まずDELコマンドの標準エラー出力を標準出力にリダイレクトし、パイプに続くFINDコマンドで標準出力に文字列が出力されているかをチェックしています。(FINDコマンドは、検索条件に一致する文字列があれば終了コードとして「0」、一致する文字列がなければ「1」が返されることから、ERRORLEVELによる判定が可能です。)
また、ログファイルなどが生成される場合は、ログファイルに記述されている文字列を検索することで正常か異常か判定する方法もあります。
findstr "エラー" C:\example.log
if %errorlevel% neq 0 (
echo エラーが発生しました。
exit /b %errorlevel%
)他には、レジストリ設定の時などでは「REG ADD」コマンドで設定した値を「REG QUERY」コマンドで取り出して、値を比較して正常か異常かを判定する方法もあります。
ファイルの存在有無による判別
ERRORLEVEL変数を使った判別が使えない場合、上に挙げた出力メッセージで正常終了と異常終了を判別する以外に、実行するコマンドによってはファイルの存在によって判別する方法もあります。
たとえば、DELコマンドならファイルの削除後にファイルの存在をチェックすることで、ファイルが正常に削除されているかを判別できます。
if not exist C:\example.log (
echo エラーが発生しました。
exit /b 1
)バッチファイルに終了コードを設定
バッチファイル自体のエラーを判定したいときは、EXITコマンドを使ってバッチファイルに終了コードを設定できます。EXITコマンドで指定した終了コードはERRORLEVELに格納されます。
たとえば、バッチファイル内でエラー発生個所に応じて異なる終了コードを設定しておけば、終了コードからどこでエラーが発生したかを判別できるでしょう。
コマンドA
if %errorlevel% neq 0 (
exit /b 1
)
コマンドB
if %errorlevel% neq 0 (
exit /b 2
)
コマンドC
if %errorlevel% neq 0 (
exit /b 3
)あとがき
作成するバッチファイルによっては、エラーハンドリングをより工夫しなければならないこともありますが、まずは上に紹介した方法を覚えておけば、大抵のケースには対応できるのではないでしょうか。