2009-04-09 393 views
220

我有一個批處理文件,用不同的參數反覆調用同一個可執行文件。如果其中一個調用返回任何級別的錯誤代碼,我該如何立即終止?如何在遇到錯誤時終止批處理文件?

基本上,我想要相當於MSBuild的ContinueOnError=false

+1

什麼命令外殼將運行你的腳本? DOS/Win9x的command.com或Win2k +的cmd.exe?既然這會造成一個不同的世界,你能否在你的問題的編輯中澄清一下? – 2009-04-09 14:58:38

回答

234

檢查errorlevelif語句,然後exit /b(退出b ATCH文件只,而不是整個過程CMD.EXE)爲其他值大於0

same-executable-over-and-over.exe /with different "parameters" 
if %errorlevel% neq 0 exit /b %errorlevel% 

如果你想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」類型的構造。我還根據CodeMonkey更新了我的代碼,儘管我在XP或Vista上進行批量黑客攻擊時從未遇到負面錯誤級別。

+8

有沒有辦法爲整個文件聲明一次? 「錯誤轉到」或類似的東西? – 2009-04-09 15:29:28

+3

+1表示負面的錯誤級別檢查。如果劇本因負面結果而默默失敗。 – devstuff 2010-09-16 04:37:56

+0

小心:enabledelayedexpansion是關鍵的,也是if/else或任何其他塊所必需的 – MarcH 2013-04-04 23:05:44

23

一個小更新,你應該改變的檢查,「如果錯誤級別1」以下......

IF %ERRORLEVEL% NEQ 0 

這是因爲XP就可以得到負數的錯誤。 0 =沒有問題,其他都是問題。

並記住DOS處理「IF ERRORLEVEL」測試的方式。如果您檢查的號碼是該號碼或更高,那麼它將返回true,因此如果您正在查找需要以255開始並減少的特定錯誤號碼。

198

|| 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% 

又見question about exiting batch file subroutine

-2
@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 
53

最短:

command || exit /b 

如果你需要,可以設置退出代碼:

command || exit /b 666 

而且你還可以登錄:

command || echo ERROR && exit /b 
1

我們不能總是依賴於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) 
0

只需使用ERRORLEVEL達到你想要的結果。 ERRORLEVEL命令中有兩個變量可確定進程是失敗還是成功,這些變量分別爲ERRORLEVEL 0ERRORLEVEL 1(1表示失敗,0表示失敗)。這裏是如何做到這一點在批處理文件中使用的示例:

echo off 
cls 
ping localhost 
errorlevel 0 goto :good 
errorlevel 1 goto :bad 

:good 
cls 
echo Good! 
echo[ 
pause 
exit 

:bad 
cls 
echo Bad! 
echo[ 
pause 
exit 

下面是詳細信息的鏈接,如果你需要它:Errorlevels

1

無論我怎樣努力,在錯誤級別始終保持0即使msbuild失敗。所以,我建我的解決方法:

生成項目,並保存記錄到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% 

GET最後一個字符,表示包含搜索字符串的行數

set result=%var:~-1% 

echo "%result%" 

如果找不到字符串,然後誤差> 0,建立失效

if "%result%"=="0" (echo "build failed") 

該解決方案是由Mechaflash的帖子在How to set commands output as a variable in a batch file

https://ss64.com/nt/syntax-substring.html

4

這裏啓發爲BASH和Windows CMD一個polyglot program運行一系列命令和退出如果他們中的任何一個失敗:

#!/bin/bash 2> nul 

:; set -o errexit 
:; function goto() { return $?; } 

command 1 || goto :error 

command 2 || goto :error 

command 3 || goto :error 

:error 

:; exit 0 
exit /b 0 

:error 
exit /b %errorlevel% 

我已經在過去使用這種類型的東西的多平臺形式continuous integration腳本。

相關問題