请注意:
c:\ temp \ 1.cmd
@echo off
setlocal
cmd /c dir aaa
IF %ERRORLEVEL% NEQ 0 GOTO fail
GOTO end
:fail
echo - Script failed
:end
endlocal
现在,如果我在命令提示符下运行它:
C:\temp> cmd
Microsoft Windows [Version 10.0.16299.967]
(c) 2017 Microsoft Corporation. All rights reserved.
C:\temp>c:\temp\1.cmd
Volume in drive C has no label.
Volume Serial Number is 4A5E-F223
Directory of C:\temp
File Not Found
- Script failed
C:\temp>echo %errorlevel%
1
C:\temp>
现在我正在Powershell中运行它:
C:\temp> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.16299.967
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.16299.967
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
C:\temp> cmd /c C:\temp\1.cmd
Volume in drive C has no label.
Volume Serial Number is 4A5E-F223
Directory of C:\temp
File Not Found
- Script failed
C:\temp> $LASTEXITCODE
0
C:\temp>
据我所知,退出代码应该正确传播。那是什么问题呢?
答案 0 :(得分:3)
为jazzdelightsme's effective solution提供一些背景信息:
执行批处理文件后, %ERRORLEVEL%
在同一cmd.exe
进程中反映该批处理文件的-隐式或显式-退出代码 执行了批处理文件。
隐式退出代码是恰好由批处理文件退出之前执行的最后一个退出代码报告语句设置的代码。
通过在批处理文件中调用 exit /b <n>
来设置 显式退出代码,以便通过退出给定的退出代码(<n>
)。
运行批处理文件的 cmd.exe
进程(始终在进程中)仅将批处理文件的 explicit 退出代码传播为其进程退出代码,即仅当批处理文件使用exit /b
时。
help exit
的措词有些混乱(也很有趣!“指定数字”),但可以解释为传达这一事实。
也许的想法是,隐式退出代码(偶然设置)不会保证向外部世界传播作为总体成功/失败指标。
以上解释了您看到的行为:
从cmd.exe
运行时,在进程中运行批处理文件的该进程在%ERRORLEVEL%
相比之下, PowerShell必须在cmd.exe
子进程 中运行批处理文件,因此只能看到cmd.exe
自己的文件如前所述,退出代码不反映批处理文件的隐式退出代码。
c:\temp\1.cmd
等同于从cmd /c c:\temp\1.cmd
运行cmd.exe
-您可以在两者中观察到相同的退出代码行为。答案 1 :(得分:1)
首先:ERRORLEVEL is not %ERRORLEVEL%。
第二,错误级别与进程退出代码不同。
尝试如下更改您的cmd脚本(请注意添加了“退出/ b 1”):
@echo off
setlocal
cmd /c dir aaa
IF %ERRORLEVEL% NEQ 0 GOTO fail
GOTO end
:fail
echo - Script failed
exit /b 1
:end
endlocal