我正在尝试Rust。我想编译一个程序,只有成功,才能运行它。我正在努力:
rustc hello.rs && hello
但即使编译失败,hello.exe也会一直运行。
如果我尝试
rustc hello.rs
echo Exit Code is %errorlevel%
我得到"退出代码是101"。
根据我的理解,唯一的真实价值是0厘米,其中101显然不是,&&懒惰评估,为什么它运行hello
?
rustc.bat
看起来像这样:
@echo off
SET DIR=%~dp0%
cmd /c "%DIR%..\lib\rust.0.11.20140519\bin\rustc.exe %*"
exit /b %ERRORLEVEL%
答案 0 :(得分:9)
非常好奇。把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,它们可以正确响应脚本的退出代码,以及响应脚本是否运行失败(可能脚本不存在)。
换句话说,如果通过CALL启动退出代码,批处理脚本只会通知&&
和||
运营商。
<强>更新强>
在仔细阅读foxidrive(现已删除)答案后,我意识到情况更复杂。
如果使用了CALL,那么一切都按预期工作 - &&
和||
响应脚本返回的ERRORLEVEL。 ERRORLEVEL可以在脚本的早期设置为1,只要没有后续脚本命令清除错误,返回的ERRORLEVEL为1就会正确报告给&&
和||
。
如果未使用CALL,则&&
和||
会响应脚本中上次执行命令的错误代码。脚本中的早期命令可能将ERRORLEVEL设置为1.但如果最后一个命令是正确执行的ECHO语句,则&&
和||
将响应ECHO命令的成功而不是ERRORLEVEL 1由脚本返回。
真正的杀手是EXIT /B 1
不 向另一个&&
或||
报告ERRORLEVEL,除非通过呼叫。条件运算符检测到EXIT命令成功执行,并忽略返回的ERRORLEVEL!
如果脚本执行的最后一个命令是:
,则可以实现预期的行为cmd /c exit %errorlevel%
无论脚本是否由CALL调用,这都会正确地将返回的ERRORLEVEL报告给&&
和||
。
以下是一些演示我的意思的测试脚本。
<强> 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
>
答案 1 :(得分:1)
快速演示证明重点:
@ECHO OFF
SETLOCAL
CALL q24983584s 0&&ECHO "part one"
ECHO done one
CALL q24983584s 101&&ECHO "part two"
ECHO done two
GOTO :EOF
其中q24983584s.bat
是
@ECHO OFF
SETLOCAL
EXIT /b %1
GOTO :EOF
按预期工作......