我有一个批处理文件,它用不同的参数反复调用相同的可执行文件。如果其中一个调用返回任何级别的错误代码,我如何使它立即终止?
基本上,我想要等效于MSBuild的ContinueOnError=false。
我有一个批处理文件,它用不同的参数反复调用相同的可执行文件。如果其中一个调用返回任何级别的错误代码,我如何使它立即终止?
基本上,我想要等效于MSBuild的ContinueOnError=false。
当前回答
一个小更新,你应该改变检查“if errorlevel 1”为以下…
IF %ERRORLEVEL% NEQ 0
这是因为在XP上你可以得到负数作为错误。0 =没问题,其他的都是问题。
记住DOS处理“IF ERRORLEVEL”测试的方式。如果您正在检查的数字是该数字或更高,它将返回true,所以如果您正在寻找特定的错误数字,您需要从255开始,然后往下算。
其他回答
一个小更新,你应该改变检查“if errorlevel 1”为以下…
IF %ERRORLEVEL% NEQ 0
这是因为在XP上你可以得到负数作为错误。0 =没问题,其他的都是问题。
记住DOS处理“IF ERRORLEVEL”测试的方式。如果您正在检查的数字是该数字或更高,它将返回true,所以如果您正在寻找特定的错误数字,您需要从255开始,然后往下算。
检查if语句中的errorlevel,然后退出/b(仅退出批处理文件,而不是整个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批处理中没有全局的“on error goto”类型的构造。我还根据CodeMonkey更新了我的代码,尽管我从未在XP或Vista上的任何批量黑客中遇到过负错误级别。
我们不能总是依赖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,即使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%
获取最后一个字符,该字符表示搜索字符串包含多少行
set result=%var:~-1%
echo "%result%"
如果未找到字符串,则错误> 0,构建失败
if "%result%"=="0" ( echo "build failed" )
该解决方案的灵感来自Mechaflash的帖子如何将命令输出设置为批处理文件中的变量
和https://ss64.com/nt/syntax-substring.html
@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