2009-04-09 405 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脚本。

相关问题