如何在遇到错误时终止批处理文件?
我有一个批处理文件,用不同的参数反复调用同一个可执行文件。如果其中一个调用返回任何级别的错误代码,我该如何立即终止?如何在遇到错误时终止批处理文件?
基本上,我想要相当于MSBuild的ContinueOnError=false
。
检查errorlevel
在if
语句,然后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上进行批量黑客攻击时从未遇到负面错误级别。
一个小更新,你应该改变的检查,“如果错误级别1”以下......
IF %ERRORLEVEL% NEQ 0
这是因为XP就可以得到负数的错误。 0 =没有问题,其他都是问题。
并记住DOS处理“IF ERRORLEVEL”测试的方式。如果您检查的号码是该号码或更高,那么它将返回true,因此如果您正在查找需要以255开始并减少的特定错误号码。
将|| 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%
@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
最短:
command || exit /b
如果你需要,可以设置退出代码:
command || exit /b 666
而且你还可以登录:
command || echo ERROR && exit /b
我们不能总是依赖于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)
只需使用ERRORLEVEL
达到你想要的结果。 ERRORLEVEL
命令中有两个变量可确定进程是失败还是成功,这些变量分别为ERRORLEVEL 0
和ERRORLEVEL 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
无论我怎样努力,在错误级别始终保持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
这里启发为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脚本。
什么命令外壳将运行你的脚本? DOS/Win9x的command.com或Win2k +的cmd.exe?既然这会造成一个不同的世界,你能否在你的问题的编辑中澄清一下? – 2009-04-09 14:58:38