加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

windows – 同一行\u0026\u0026或||看不到的命令脚本退

发布时间:2020-12-13 22:34:45 所属栏目:Windows 来源:网络整理
导读:考虑一个名为t.cmd的命令脚本,它只包含以下两行: @exit /b 123@echo If you see this,THEN EXIT FAILED.. 因此,脚本只是将脚本执行过程的退出代码设置为123,但不会杀死cmd.exe.最后的回声确认退出实际上导致立即返回(其输出不应出现). 现在执行此脚本,然后
考虑一个名为t.cmd的命令脚本,它只包含以下两行:

@exit /b 123
@echo If you see this,THEN EXIT FAILED..

因此,脚本只是将脚本执行过程的退出代码设置为123,但不会杀死cmd.exe.最后的回声确认退出实际上导致立即返回(其输出不应出现).

现在执行此脚本,然后打印出%errorlevel%:

>t.cmd

>echo %errorlevel%
123

到目前为止一切都那么好:一切都表现得与预期一致.

但现在使用&&&&用于条件执行:

>t.cmd && echo %errorlevel%
123

我不指望这样:如果t.cmd真的返回非0退出代码,那么它应该在那之后停止所有&& (即回声)来自执行.我们看到它打印的事实意味着它DID执行.到底他妈发生了什么?

如果在一行上执行上述所有操作,请使用||用于条件执行:

>t.cmd || echo %errorlevel%

>

这种行为也与我的预期相反(尽管它与上面的&&行为一致).

请注意,这种奇怪的行为仅适用于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

在这里,&&和||立即看到失败的bogus命令的退出代码.

那么为什么cmd文件的行为有所不同呢?

在File redirection in Windows and %errorlevel%中观察到cmd.exe中可能存在的相关错误

另外,我知道ERRORLEVEL is not %ERRORLEVEL%

顺便说一句,上面的代码都是在Win 7 Pro 64位框上执行的.我不知道其他版本的Windows如何表现.

解决方法

随着t.bat略有修改如下:

@exit /b 123%~1
@echo If you see this,THEN EXIT FAILED..

想出下一个输出:

==>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

==>

资源

>(%~1等特殊页面)Command Line arguments (Parameters)
>(特殊页面)EnableDelayedExpansion

编辑以启用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

==>

编辑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!

输出(来自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

==>

注意

> ||显示错误级别1虽然’abcd’未被识别,但错误应该是9009
> ||为FIND保持errorlevel 2不变:无效的开关错误.
> ||分支在调用t.cmd 333时进行评估
>&& branch在t.cmd 222中进行求值.

开(通话)见DBenham’s answer:

If you want to force the errorlevel to 0,then you can use this
totally non-intuitive,but very effective syntax: (call ). The space
after call is critical.

If you want to set the errorlevel to 1,you can use (call). It
is critical that there not be any space after call.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读