在Windows命令提示符上,'&&' seemingly忽略的错误码

8 浏览
0 Comments

在Windows命令提示符上,'&&' seemingly忽略的错误码

我有一些用于自动化应用程序构建流程的批处理脚本,其中大部分涉及使用“&&”运算符链接命令。诚然,我对Linux更有经验,但根据这个经验,“some_command && other_command”应该导致只有在“some_command”的退出码为0时才运行“other_command”。这个答案和这个答案似乎都支持这个观点。然而,在Windows的cmd.exe上似乎并非如此,所有的脚本都会运行,无论前一个命令的错误码如何。\n为了确信自己没有发疯,我决定进行一个简单的测试。考虑一下返回退出码1的“test.bat”:\n@echo off\nEXIT /B 1\n运行“test.bat && echo This shouldn\'t print”会打印出“This shouldn\'t print”。但由于退出码明显为1,不应该调用“echo”。我已经测试过错误码实际上是1,使用“%errorlevel%”变量,它们的输出符合预期(运行脚本前为0,运行后为1)。\n在Linux上,我尝试了同样的事情。这是“test.sh”:\n#!/bin/bash\nexit 1\n运行“./test.sh && echo \"This shouldn\'t print\"”没有输出,正是我预期的结果。\n这里到底发生了什么?\n(注意:操作系统是Windows 7 Enterprise)

0
0 Comments

在Windows命令提示符下,使用&&操作符时,错误代码似乎被忽略的原因是,如果在批处理脚本中不使用call来运行批处理脚本,则&&操作符无法接收到批处理脚本返回的ErrorLevel值。

解决方法是,在运行批处理脚本时使用call命令,如下所示:

call test.bat && echo This shouldn't print

这样,在没有使用call的情况下,&&操作符不会接收到批处理脚本返回的ErrorLevel值。

当在一个批处理文件中运行另一个批处理文件时,需要使用call命令以便返回到调用的批处理文件;如果没有使用call,执行会在被调用的批处理文件完成后终止。例如:

call test.bat

echo This is going to be displayed.

但是,如果这样运行test.bat:

test.bat

echo You will never see this!

当test.bat参与多个命令组合的命令行时(使用连接运算符&、条件运算符&&和||,甚至是括号块()中的代码),即使没有使用call,所有紧随test.bat之后的命令都会被执行。这是因为命令解释器已经解析了整个命令行/块。

然而,当使用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.

但是,如果没有使用call,会得到如下结果:

test.bat & echo This is printed.

echo But this is not!

以及:

test.bat && echo Even this is printed!

echo Neither is this!

以及:

test.bat || echo But this is not printed!

echo And this is not either!

以及:

(

call test.bat

echo This is printed.

echo And this as well.

)

看起来,&&和||操作符接收到的ErrorLevel值为0,即使在执行test.bat之前已经设置了ErrorLevel。当使用if ErrorLevel时,行为类似:

test.bat & if ErrorLevel 1 echo This is not printed!

以及:

set = & rem This constitutes a syntax error.

test.bat & if ErrorLevel 1 echo This is still not printed!

请注意,test.bat后面的命令会在批处理脚本之后执行,即使没有使用call。

关于这一点还有更多的细节。在test.bat && echo This...这一行中,test.bat文件没有通过call调用,这意味着该批处理文件不会返回,因此实际上没有任何返回的ErrorLevel。之后的命令之所以执行是因为整行已经被解析,但是在该行之下的任何行都不会执行(因为执行在test.bat文件结束时终止)。call命令只是在test.bat文件结束后,使执行返回到这一行,所以&&操作符才能起作用。

以上是该问题的原因和解决方法。

0