在Windows命令提示符下,"&&"似乎忽略了错误代码

Sil*_*ter 0 windows batch-file

我有一些批处理脚本用于自动化应用程序构建过程,其中大多数涉及使用&&运算符将命令链接在一起.不可否认,我对Linux更有经验,但基于该经验some_command && other_command应该导致other_command运行iff some_command返回退出代码0.这个答案这个答案似乎都同意这一点.但是,在Windows cmd.exe中似乎不是这种情况,所有脚本都会运行,而不管之前的错误代码如何.

我决定做一个简单的测试来说服自己我不会疯狂.考虑一下test.bat,它返回退出代码1:

@echo off
EXIT /B 1
Run Code Online (Sandbox Code Playgroud)

运行test.bat && echo This shouldn't print打印'这不应该打印'.但由于退出代码显然为1,echo因此不应调用.我已经测试过错误代码实际上是1使用%errorlevel%变量,它们按预期出现(在我运行脚本之前为0,之后为1).

在Linux上我尝试了同样的事情.这是test.sh:

#!/bin/bash
exit 1
Run Code Online (Sandbox Code Playgroud)

运行./test.sh && echo "This shouldn't print"没有输出,正是我所期望的.

这里发生了什么?

(注意:操作系统是Windows 7企业版)

asc*_*pfl 6

您需要使用它call来运行批处理脚本,如下所示:

call test.bat && echo This shouldn't print
Run Code Online (Sandbox Code Playgroud)

如果没有call,则&&操作员不会收到ErrorLevel批处理脚本返回的内容.


当您从另一个批处理文件中运行批处理文件时,您需要使用call以便返回到调用批处理文件; 没有call,一旦被调用的批处理文件完成,执行就会终止......:

call test.bat
echo This is going to be displayed.
Run Code Online (Sandbox Code Playgroud)

...但:

test.bat
echo You will never see this!
Run Code Online (Sandbox Code Playgroud)

当运行test.bat参与命令行,其中多个命令被组合(使用并置运算符&,条件那些&&||,或的括号内代码甚至一个块()),所有的命令下面test.bat是ecexuted即使call不使用.这是因为命令解释器已经解析了整个命令行/块.

但是,在call使用时,将ErrorLevel接收批处理文件返回的值(1在我们的情况下),并且以下命令的行为相应:

call test.bat & echo This is always printed.
echo And this is also always printed.

call test.bat && echo This is not printed.

call test.bat || echo But this is printed.

(
    call test.bat
    echo This is printed too.
    echo And again this also.
)

call test.bat & if ErrorLevel 1 echo This is printed.
Run Code Online (Sandbox Code Playgroud)

但没有call你会得到这个...:

test.bat & echo This is printed.
echo But this is not!
Run Code Online (Sandbox Code Playgroud)

...和...:

test.bat && echo Even this is printed!
echo Neither is this!
Run Code Online (Sandbox Code Playgroud)

...和...:

test.bat || echo But this is not printed!
echo And this is not either!
Run Code Online (Sandbox Code Playgroud)

...和:

(
    call test.bat
    echo This is printed.
    echo And this as well.
)
Run Code Online (Sandbox Code Playgroud)

看来,&&||运营商收到ErrorLevel0-即使是在案件ErrorLevel之前已经设定test.bat执行,很奇怪.此外,当if ErrorLevel使用时,该行为是相似的:

test.bat & if ErrorLevel 1 echo This is not printed!
Run Code Online (Sandbox Code Playgroud)

...和...:

set = & rem This constitutes a syntax error.
test.bat & if ErrorLevel 1 echo This is still not printed!
Run Code Online (Sandbox Code Playgroud)

需要注意的是后面的命令test.bat执行的批处理脚本,甚至没有call.

  • 这里涉及更多细节.在`test.bat && echo this ...`行中,`test.bat`文件通过`call`被_not_调用; 这意味着批处理文件_never_返回,所以实际上没有任何`ErrorLevel`**_返回_**.执行"&&"或"&"之后的命令只是因为整行已经被解析,但是在这一行之下的任何行都不会执行(因为执行结束于`test.bat`文件).`call`命令只是在`test.bat`文件结束后执行,执行返回到这一行,所以`&&`可以完成它的工作...... (2认同)