我正在试验 Rust。我想编译一个程序,只有编译成功了,才运行。所以我正在尝试:
rustc hello.rs && hello
但 hello.exe 始终运行,即使编译失败也是如此。
如果我尝试
rustc hello.rs
echo Exit Code is %errorlevel%
我得到“退出代码是 101”。
据我了解,cmd 中唯一的真值是 0,而 101 显然不是,而且 && 是延迟求值的,那么为什么它会运行 hello
?
rustc.bat
看起来像这样:
@echo off
SET DIR=%~dp0%
cmd /c "%DIR%..\lib\rust.0.11.20140519\bin\rustc.exe %*"
exit /b %ERRORLEVEL%
最佳答案
很好奇这个。把 CALL 放在前面,一切都应该没问题。
call rustc hello.rs && hello
我不完全理解这个机制。我知道 &&
和 ||
不直接读取动态 %errorlevel%
值,而是在某个较低的级别运行。它们根据最近执行的命令的结果有条件地触发,而不考虑当前的 %errorlevel%
值。 ||
甚至可以针对未设置 %errorlevel%
的故障触发!参见 File redirection in Windows and %errorlevel%和 batch: Exit code for "rd" is 0 on error as well例如。
您的 rustc
是一个批处理文件,行为会根据是否使用 CALL 而改变。如果没有 CALL,&&
和 ||
运算符仅响应命令是否运行 - 它们忽略脚本的退出代码。使用 CALL,除了在脚本运行失败(可能脚本不存在)时做出响应外,它们还可以正确响应脚本的退出代码。
换句话说,批处理脚本仅通知 &&
和 ||
运算符(operator)有关通过 CALL 启动的退出代码。
更新
仔细阅读 foxidrive(现已删除)的回答后,我意识到情况更加复杂。
如果使用 CALL,那么一切都会按预期工作 - &&
和 ||
响应脚本返回的 ERRORLEVEL。 ERRORLEVEL 可能在脚本的早期设置为 1,只要后续脚本命令没有清除错误,返回的 1 的 ERRORLEVEL 将被正确地报告给 &&
和 ||
.
如果不使用 CALL,则 &&
和 ||
响应脚本中最后执行 命令的错误代码。脚本中的早期命令可能会将 ERRORLEVEL 设置为 1。但如果最后一个命令是正确执行的 ECHO 语句,则 &&
和 ||
响应成功ECHO 命令而不是脚本返回的 1 的 ERRORLEVEL。
真正的 killer 是 EXIT/B 1
not 将 ERRORLEVEL 报告给 &&
或 ||
除非脚本是通过 CALL 调用的。条件运算符检测到EXIT命令执行成功,忽略返回的ERRORLEVEL!
如果脚本最后执行的命令是:
cmd /c exit %errorlevel%
这将正确地将返回的 ERRORLEVEL 报告给 &&
和 ||
,无论脚本是否被 CALL 调用。
这里有一些测试脚本可以证明我的意思。
test1.bat
@echo off
:: This gives the correct result regardless if CALL is used or not
:: First clear the ERRORLEVEL
(call )
:: Now set ERRORLEVEL to 1
(call)
test2.bat
@echo off
:: This only gives the correct result if CALL is used
:: First clear the ERRORLEVEL
(call )
:: Now set ERRORLEVEL to 1
(call)
rem This command interferes with && or || seeing the returned errorlevel if no CALL
test3.bat
@echo off
:: This only gives the correct result if CALL is used
:: First clear the ERRORLEVEL
(call )
:: Now set ERRORLEVEL to 1
(call)
rem Ending with EXIT /B does not help
exit /b %errorlevel%
test4.bat
@echo off
:: This gives the correct result regardless if CALL is used or not
:: First clear the ERRORLEVEL
(call )
:: Now set ERRORLEVEL to 1
(call)
rem The command below solves the problem if it is the last command in script
cmd /c exit %errorlevel%
现在使用和不使用 CALL 进行测试:
>cmd /v:on
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
>test1&&echo Success, yet errorlevel=!errorlevel!||echo Failure with errorlevel=!errorlevel!
Failure with errorlevel=1
>test2&&echo Success, yet errorlevel=!errorlevel!||echo Failure with errorlevel=!errorlevel!
Success, yet errorlevel=1
>test3&&echo Success, yet errorlevel=!errorlevel!||echo Failure with errorlevel=!errorlevel!
Success, yet errorlevel=1
>test4&&echo Success, yet errorlevel=!errorlevel!||echo Failure with errorlevel=!errorlevel!
Failure with errorlevel=1
>call test1&&echo Success, yet errorlevel=!errorlevel!||echo Failure with errorlevel=!errorlevel!
Failure with errorlevel=1
>call test2&&echo Success, yet errorlevel=!errorlevel!||echo Failure with errorlevel=!errorlevel!
Failure with errorlevel=1
>call test3&&echo Success, yet errorlevel=!errorlevel!||echo Failure with errorlevel=!errorlevel!
Failure with errorlevel=1
>call test4&&echo Success, yet errorlevel=!errorlevel!||echo Failure with errorlevel=!errorlevel!
Failure with errorlevel=1
>
关于windows - 为什么 cmd 在我使用 && 时运行我的第二个命令,即使第一个命令失败了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24583984/