Har*_*nch 4 windows cmd batch-file
考虑一个名为t.cmd的命令脚本,它只包含以下两行:
@exit /b 123
@echo If you see this, THEN EXIT FAILED..
Run Code Online (Sandbox Code Playgroud)
因此,脚本只是将脚本执行过程的退出代码设置为123,但不会杀死cmd.exe.最后的回声确认退出实际上导致立即返回(其输出不应出现).
现在执行此脚本,然后打印出%errorlevel%:
>t.cmd
>echo %errorlevel%
123
Run Code Online (Sandbox Code Playgroud)
到目前为止一切都那么好:一切都表现得与预期一致.
但现在在一行上执行上述所有操作,使用&&进行条件执行:
>t.cmd && echo %errorlevel%
123
Run Code Online (Sandbox Code Playgroud)
我不指望这样:如果t.cmd确实返回非0退出代码,那么它应该在执行之后停止&&(即echo)之后的所有内容.我们看到它打印的事实意味着它DID执行.到底他妈发生了什么?
如果在一行上执行上述所有操作,请使用|| 用于条件执行:
>t.cmd || echo %errorlevel%
>
Run Code Online (Sandbox Code Playgroud)
这种行为也与我的预期相反(尽管它与上面的&&行为一致).
请注意,这种奇怪的行为仅适用于bat文件,但不适用于"原始命令".
证明:考虑以下命令行交互,而不是调用t.cmd,我尝试执行bogus命令abcdef:
>abcdef
'abcdef' is not recognized as an internal or external command,
operable program or batch file.
>echo %errorlevel%
9009
>abcdef && echo %errorlevel%
'abcdef' is not recognized as an internal or external command,
operable program or batch file.
>abcdef || echo %errorlevel%
'abcdef' is not recognized as an internal or external command,
operable program or batch file.
9009
Run Code Online (Sandbox Code Playgroud)
这里,&&和|| 立即看到失败的bogus命令的退出代码.
那么为什么cmd文件的行为有所不同呢?
在Windows中的文件重定向中观察到cmd.exe中可能存在的相关错误,并且%errorlevel%
另外,我知道ERRORLEVEL不是%ERRORLEVEL%
顺便说一句,上面的代码都是在Win 7 Pro 64位框上执行的.我不知道其他版本的Windows如何表现.
随着t.bat略作如下修改:
@exit /b 123%~1
@echo If you see this, THEN EXIT FAILED..
Run Code Online (Sandbox Code Playgroud)
想出下一个输出:
==>t.bat 1
==>echo %errorlevel%
1231
==>t.bat 2&echo %errorlevel%
1231
==>echo %errorlevel%
1232
==>cmd /V /C t.bat 3^&echo !errorlevel!
1233
==>echo %errorlevel%
0
==>cmd /V /C t.bat 4^&echo !errorlevel!^&exit /B !errorlevel!
1234
==>echo %errorlevel%
1234
==>
Run Code Online (Sandbox Code Playgroud)
资源
%~1等特殊页面)命令行参数(参数)编辑启发EnableDelayedExpansion:
==>cmd /v
Microsoft Windows [Version 6.3.9600]
(c) 2013 Microsoft Corporation. All rights reserved.
==>t.bat 5&echo !errorlevel!
1235
==>echo %errorlevel%
1235
==>
Run Code Online (Sandbox Code Playgroud)
编辑2以启发(或混淆?)&&和||.将下一个代码段保存为errlevels.cmd:
@ECHO ON >NUL
@SETLOCAL enableextensions enabledelayedexpansion
(call )
@echo ^(call ^) command clears errorlevel %errorlevel%
abcd /G>NUL 2>&1
@echo abcd /G: "'abcd' not recognized" errorlevel %errorlevel%
abcd /G>NUL 2>&1 && echo YES !errorlevel! || echo NO !errorlevel!
@echo abcd /G: ^|^| changed errorlevel %errorlevel%
find /G >NUL 2>&1 && echo YES !errorlevel! || echo NO !errorlevel!
@echo find /G: ^|^| unchanged errorlevel %errorlevel%
call t.cmd 333 && echo YES !errorlevel! || echo NO !errorlevel!
type t.cmd
t.cmd 222 && echo YES !errorlevel! || echo NO !errorlevel!
Run Code Online (Sandbox Code Playgroud)
输出(来自errlevels.cmd):
==>errlevels.cmd
==>(call )
(call ) command clears errorlevel 0
==>abcd /G 1>NUL 2>&1
abcd /G: "'abcd' not recognized" errorlevel 9009
==>abcd /G 1>NUL 2>&1 && echo YES !errorlevel! || echo NO !errorlevel!
NO 1
abcd /G: || changed errorlevel 1
==>find /G 1>NUL 2>&1 && echo YES !errorlevel! || echo NO !errorlevel!
NO 2
find /G: || unchanged errorlevel 2
==>call t.cmd 333 && echo YES !errorlevel! || echo NO !errorlevel!
NO 333
==>type t.cmd
@exit /B %~1
==>t.cmd 222 && echo YES !errorlevel! || echo NO !errorlevel!
YES 222
==>
Run Code Online (Sandbox Code Playgroud)
注意
||显示错误级别1虽然'abcd' not recognized误差应9009同时||保持errorlevel 2不变的FIND: Invalid switch错误.||分支评估的call t.cmd 333同时,&&分支评估t.cmd 222.在(call )看到DBenham的答案:
如果你想强制使用
errorlevelto0,那么你可以使用这种完全不直观但非常有效的语法:(call ).之后的空间call至关重要.如果要设置
errorlevel为1,则可以使用(call).至关重要的是,之后没有任何空间call.
| 归档时间: |
|
| 查看次数: |
1300 次 |
| 最近记录: |