我正在尝试Rust.我想编译一个程序,只有成功,才能运行它.所以我在尝试:
rustc hello.rs && hello
Run Code Online (Sandbox Code Playgroud)
但是即使编译失败,hello.exe也会一直运行.
如果我试试
rustc hello.rs
echo Exit Code is %errorlevel%
Run Code Online (Sandbox Code Playgroud)
我得到"退出代码是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%
Run Code Online (Sandbox Code Playgroud)
很好奇这个.把CALL放在前面,一切都应该没问题.
call rustc hello.rs && hello
Run Code Online (Sandbox Code Playgroud)
我不完全理解这个机制.我知道&&并且||不%errorlevel%直接读取动态值,而是在较低级别操作.无论当前%errorlevel%值如何,它们都会根据最近执行的命令的结果有条件地触发.该||甚至可以触发该不设置失败%errorlevel%!请参阅Windows中的文件重定向和%errorlevel%和批处理:对于示例,出错"rd"的退出代码为0.
您rustc是批处理文件,行为会根据是否使用CALL而更改.如果没有呼叫时,&&与||运营商只响应命令是否跑或不-他们忽视了脚本的退出代码.使用CALL,它们可以正确响应脚本的退出代码,以及响应脚本是否无法运行(可能脚本不存在).
换句话说,如果通过CALL启动退出代码,批处理脚本只会通知操作员&&和||操作员.
UPDATE
在仔细阅读foxidrive(现已删除)答案后,我意识到情况更复杂.
如果使用了CALL,那么一切都按预期工作 - &&并||响应脚本返回的ERRORLEVEL.ERRORLEVEL可以在脚本的早期设置为1,只要没有后续脚本命令清除错误,返回的ERRORLEVEL为1将正确报告给&&和||.
如果不使用CALL,然后&&和||回应的错误代码上次执行的脚本命令.在剧本的早期命令可以设置ERRORLEVEL为1.但是,如果最后一个命令是执行得当,那么ECHO语句&&和||命令echo而不是1脚本返回的ERRORLEVEL的成功作出回应.
真正的杀手锏是EXIT /B 1不不 ERRORLEVEL的报告&&或||除非脚本通过CALL调用.条件运算符检测到EXIT命令成功执行,并忽略返回的ERRORLEVEL!
如果脚本执行的最后一个命令是:
cmd /c exit %errorlevel%
Run Code Online (Sandbox Code Playgroud)
这将返回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)
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
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%
Run Code Online (Sandbox Code Playgroud)
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%
Run Code Online (Sandbox Code Playgroud)
现在使用和不使用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
>
Run Code Online (Sandbox Code Playgroud)