回答:
チェックerrorlevel
してif
、文、及びexit /b
(出口Bの 0以外の値のみATCHファイル全体ではなく、cmd.exeのプロセス)。
same-executable-over-and-over.exe /with different "parameters"
if %errorlevel% neq 0 exit /b %errorlevel%
エラーレベルの値をバッチファイルの外に伝播したい場合
if %errorlevel% neq 0 exit /b %errorlevel%
しかし、これが内部にあるfor
場合は、少し注意が必要です。次のようなものが必要になります。
setlocal enabledelayedexpansion
for %%f in (C:\Windows\*) do (
same-executable-over-and-over.exe /with different "parameters"
if !errorlevel! neq 0 exit /b !errorlevel!
)
編集:コマンドごとにエラーを確認する必要があります。cmd.exe / command.comバッチには、グローバルな「エラー時のgoto」タイプのコンストラクトはありません。また、XPまたはVistaでのバッチハッキングで負のエラーレベルに遭遇したことはありませんが、CodeMonkeyごとにコードを更新しました。
neq
)の有効化/無効化はif not errorlevel 1 exit /B
、Microsoftのサポート記事「コマンドリダイレクト演算子の使用」およびコマンドif /?
ウィンドウでの実行時のヘルプ出力で説明されているように、使用に関係ありません。現在のエラーレベル(終了コード)は、によるバッチファイルの処理の終了時に保持されますexit /B
。注:exit
パラメーターを使用/B
するには、有効なコマンド拡張機能が必要です。GOTO:EOF
|| goto :label
各行に追加して、を定義し:label
ます。
たとえば、次の.cmdファイルを作成します。
@echo off
echo Starting very complicated batch file...
ping -invalid-arg || goto :error
echo OH noes, this shouldn't have succeeded.
goto :EOF
:error
echo Failed with error #%errorlevel%.
exit /b %errorlevel%
バッチファイルサブルーチンの終了に関する質問も参照してください。
command || (SET ErrorLine=102 && goto :error)
||
、最初に作成されたものだと私には思えます。特にgotoではないかもしれませんが、Fowlが述べたように「これをエラーで実行してください」私の質問は、これがすべてのゼロ以外の終了コードで機能するかどうかです。ポジティブのみ?
cmd /k exit -1 && echo success || echo fail
。自分で証明してください--印刷に失敗します。
command || exit /b %errorlevel%
一番短い:
command || exit /b
必要に応じて、終了コードを設定できます。
command || exit /b 666
また、ログに記録することもできます。
command || echo ERROR && exit /b
%ERRORLEVEL%
あなたがを呼び出すときは触れられていないexit /b
ので、エラーコードが転送されます
1つのマイナーアップデートで、「if errorlevel 1」のチェックを次のように変更する必要があります...
IF %ERRORLEVEL% NEQ 0
これは、XPでは負の数をエラーとして取得できるためです。0 =問題なし、それ以外は問題あり。
また、DOSが「IF ERRORLEVEL」テストを処理する方法を覚えておいてください。チェックしている番号がその番号以上の場合はtrueを返します。特定のエラー番号を探している場合は、255から始めて作業を進める必要があります。
以下は、一連のコマンドを実行し、それらのいずれかが失敗した場合に終了するBASHおよびWindows CMDのポリグロットプログラムです。
#!/bin/bash 2> nul
:; set -o errexit
:; function goto() { return $?; }
command 1 || goto :error
command 2 || goto :error
command 3 || goto :error
:; exit 0
exit /b 0
:error
exit /b %errorlevel%
私は過去にこのタイプのものを複数プラットフォームの継続的統合スクリプトに使用しました。
私は、OR形式のコマンドを好んでいます(各コマンドの後にifがあるのではなく)。ただし、これを行う素朴な方法command || exit /b %ERRORLEVEL%
は間違っています。
これは、バッチが変数が使用されているときではなく、最初に読み取られたときに変数を展開するためです。これは、command
上の行のが失敗した場合、バッチファイルは正常に終了しますが、戻りコード0で終了することを意味します%ERRORLEVEL%
。これは、行の先頭にあるの値だからです。明らかに、これはスクリプトでは望ましくないため、次のように遅延拡張を有効にする必要
があります。
SETLOCAL EnableDelayedExpansion
command-1 || exit /b !ERRORLEVEL!
command-2 || exit /b !ERRORLEVEL!
command-3 || exit /b !ERRORLEVEL!
command-4 || exit /b !ERRORLEVEL!
このスニペットはコマンド1〜4を実行し、それらのいずれかが失敗すると、失敗したコマンドと同じ終了コードで終了します。
多くの場合、外部プログラムまたはバッチスクリプトは終了コードを返さないため、ERRORLEVELに常に依存することはできません。
その場合、次のようなエラーの一般的なチェックを使用できます。
IF EXIST %outfile% (DEL /F %outfile%)
CALL some_script.bat -o %outfile%
IF NOT EXIST %outfile% (ECHO ERROR & EXIT /b)
そして、プログラムがコンソールに何かを出力する場合は、それもチェックできます。
some_program.exe 2>&1 | FIND "error message here" && (ECHO ERROR & EXIT /b)
some_program.exe 2>&1 | FIND "Done processing." || (ECHO ERROR & EXIT /b)
どのように試しても、msbuildが失敗した場合でも、エラーレベルは常に0のままです。だから私は私の回避策を構築しました:
プロジェクトをビルドし、ログをBuild.logに保存します
SET Build_Opt=/flp:summary;logfile=Build.log;append=true
msbuild "myproj.csproj" /t:rebuild /p:Configuration=release /fl %Build_Opt%
ビルドログで「0エラー」文字列を検索し、結果をvarに設定します
FOR /F "tokens=* USEBACKQ" %%F IN (`find /c /i "0 Error" Build.log`) DO (
SET var=%%F
)
echo %var%
検索文字列を含む行数を示す最後の文字を取得します
set result=%var:~-1%
echo "%result%"
文字列が見つからない場合、エラー> 0、ビルド失敗
if "%result%"=="0" ( echo "build failed" )
そのソリューションは、バッチファイルでコマンド出力を変数として設定する方法に関するMechaflashの投稿に触発されました
for /f %%F in ('type build.log^|find /c /i "0 Error") do set result=%%F
。注:find "0 Error"
も検索されます10 Errors
。
@echo off
set startbuild=%TIME%
C:\WINDOWS\Microsoft.NET\Framework\v3.5\msbuild.exe c:\link.xml /flp1:logfile=c:\link\errors.log;errorsonly /flp2:logfile=c:\link\warnings.log;warningsonly || goto :error
copy c:\app_offline.htm "\\lawpccnweb01\d$\websites\OperationsLinkWeb\app_offline.htm"
del \\lawpccnweb01\d$\websites\OperationsLinkWeb\bin\ /Q
echo Start Copy: %TIME%
set copystart=%TIME%
xcopy C:\link\_PublishedWebsites\OperationsLink \\lawpccnweb01\d$\websites\OperationsLinkWeb\ /s /y /d
del \\lawpccnweb01\d$\websites\OperationsLinkWeb\app_offline.htm
echo Started Build: %startbuild%
echo Started Copy: %copystart%
echo Finished Copy: %TIME%
c:\link\warnings.log
:error
c:\link\errors.log