我有一个批处理文件,它用不同的参数反复调用相同的可执行文件。如果其中一个调用返回任何级别的错误代码,我如何使它立即终止?

基本上,我想要等效于MSBuild的ContinueOnError=false。


当前回答

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

无论我如何尝试,错误级别总是保持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

下面是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)。然而,幼稚的方式 命令|| exit /b %ERRORLEVEL%错误。

这是因为批处理在第一次读取一行时展开变量 而不是被使用的时候。这意味着如果在命令行中 上述失败,批处理文件正常退出,但退出时返回代码为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,如果其中任何一个失败,它将继续执行 使用与失败命令相同的退出代码退出。