意外的双与符号/管道符号行为在链接批处理脚本时出现

7

我的foo.bat文件:

exit /b 1

我在命令提示符中执行的操作:

foo.bat && echo "OK"

结果:

exit /b 1
"OK"

然而,当我使用双竖线时,echo不会发生:

foo.bat || echo "OK"

结果:

exit /b 1

这正好与我预期的 && 和 || 的行为相反。请参见https://ss64.com/nt/call.html,其中说:

commandA && commandB 如果运行 commandA 成功,则运行 commandB

commandA || commandB 如果运行 commandA 失败,则运行 commandB

我是不是疯了?我错过了什么?


2
call foo.bat && echo ok || echo fail 可以正常工作(我知道,这并不能解释所描述的行为,因为 - 嗯,我没有解释。我和你一样感到惊讶) - Stephan
6
要运行foo.bat并获取它的退出代码,必须使用call命令,并且可以通过&&和/或||来获取退出代码;否则,执行控制不会(真正地)返回到调用脚本。但由于已经读取和解析了完整的命令行(带有&&||),因此似乎已经完全执行,但仅仅是从启动foo.bat而非从其返回的退出代码中成功执行... - aschipfl
1
不是 - &&|| 响应脚本中执行的最后一个命令的返回代码。请参阅我的答案。 - dbenham
2个回答

4

||&&会响应上一个命令的返回代码(左边执行的最后一个命令)。所有程序无论在何种情况下都会以错误代码退出。

EXIT /B 1设置批处理ERRORLEVEL,这是cmd.exe概念中严格规定的。

返回代码和ERRORLEVEL不是同一个东西!

当批处理文件被执行时,只有通过CALL调用批处理文件时,退出的ERRORLEVEL才会作为返回代码返回。

当未使用CALL调用批处理文件时,&&||将响应脚本中最后执行的命令。

EXIT /B 1将ERRORLEVEL设置为1,但是命令已成功执行,因此返回代码为0。

当使用CALL时,CALL命令在脚本终止后查看ERRORLEVEL,并将返回代码设置为ERRORLEVEL。


0

foo.bat 成功运行。它将错误级别设置为 1。因此,&& / || 显示了 success 的结果。

如果 oof.bat 不存在,则无法成功运行。它没有将错误级别设置为 1(在我的机器上设置为 9009)。因此,&& / || 显示了 fail 的结果。

考虑使用 echoerrorlevel.bat

@ECHO OFF
ECHO errorlevel=%ERRORLEVEL%

然后foo&echoerrorlevel显示由foo返回的errorlevel,但oof&echoerrorlevel在一个可以通过标准的2>nul抑制的投诉后显示errorlevel 9009。


1
没错。我有时会忘记 &&|| 不会评估错误级别,而是命令的成功/失败 - 这并不总是相同的。 - Stephan
2
你差不多懂了。没错,当 oof.bat 不存在时,“||”会因为 9009 错误而触发。但是,如果 foo.bat 存在并且上一个由 foo 执行的命令返回错误,那么“||”也会触发。&& 和 || 始终响应最后执行的命令。(如果重定向失败,则可能成为最后的“命令”)请参阅我的答案。 - dbenham

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接