コマンドプロンプトの errorlevel を確認してエラーなら処理を終了する方法
基本中の基本なんですが、最近はエラーが起こったら処理を終了することが重要になってくるとき、例えば「コマンドプロンプトしか使えない状況でCI回したい」みたいな縛りプレイしてるときに使ってます。具体的にはJenkinsのジョブを失敗させるためですが。
手順
まず、バッチファイルに以下の様なサブルーチンを用意しておきます。
:SuccessOrDie if not %errorlevel% == 0 ( echo [ERROR] :P exit 1 ) exit /b 0
これをerrorlevel
に戻り値を返すコマンドのあとにcall
で呼び出します。
xcopy src\hoge.dll dest\ /Y /F call :SuccessOrDie
もしエラーが発生していたら(errorlevel
が0
でなかったら)exit 1
が実行されコマンドプロンプトが戻り値1
、つまりエラーで終了します。Jenkinsだとこれだけでジョブを失敗させることができます。
一方、エラーがなかった場合(errorlevel
が0
の場合)はexit /b 0
が実行されます。/b
オプションによってサブルーチンを終了し呼び出し元に戻ることができます。
バッチファイルではよくgoto
使ってエラー処理をしているのを見かけますが、呼び出し元に戻りたいのに加えて、思わぬバグが生まれることがあるので使うのを避けて、call
とexit
の組み合わせを使っています。
errorlevelを含む条件式での注意点
if not errorlevel 0 exit 1
って書いてしまうと「0以上ではないとき終了する」になるので、errorlevel
が負のときにしかexit
が実行されません。
if not %errorlevel% == 0 exit 1
というように展開した上で文字列での比較を行うことで「0ではないとき終了」するようになります。
手動で実行したい!
基本的にはCIサーバでコンソール出力を記録しながら使うことを前提としたバッチファイルですが、CIとかよくわからんから手動でもログを残して実行できるようにしておいてくれないと困るって言う人が稀によくいます。
そういうときは以下のような処理を書いた手動実行用のラッパーを用意しています。
@echo build.batを実行します。 @echo ログは build.bat.logに出力されます。 @pause @echo 実行中... @call build.bat > build.bat.log 2>&1
このバッチファイルをダブルクリックするだけでログ出力まで行います。
サンプル全文
ここまでで紹介したあれこれをまとめたサンプルの全文です。
@echo off set SELF_PATH=%~dp0 cd /d %SELF_PATH% xcopy src\hode.dll dest\ /Y /F call :SuccessOrDie goto end :SuccessOrDie if not %errorlevel% == 0 ( echo [ERROR] :P cd /d %SELF_PATH% exit 1 ) exit /b 0 :end echo [SUCCESS] :) echo on exit 0