请注意:
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
Run Code Online (Sandbox Code Playgroud)
现在,如果我在命令提示符下运行它:
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>
Run Code Online (Sandbox Code Playgroud)
现在我从 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>
Run Code Online (Sandbox Code Playgroud)
据我所知,退出代码应该正确传播。那么,问题是什么?
注意:此答案在新信息曝光后被大幅重写。
用一些一般指导和背景信息补充jazzdelightsme 的有效解决方案:
当从外部 调用批处理文件时cmd.exe
,例如从 PowerShell,调用它作为 -cmd /c file.cmd ... `& exit
注意[1]的`
-escaping - 以确保它的行为与从内部调用时的退出代码(错误级别)一样,即以确保该批处理文件的退出代码可靠地变成的进程退出代码。&
cmd.exe
cmd.exe
如果没有的`& exit
解决办法,你只有当你确保获得所需的行为都通过以下方式之一的代码路径退出-和缺少代码路径是一个容易犯的错误:
exit
有没有参数,这些参数正确转发了最近执行的命令的退出代码。
exit
不/b
立即cmd.exe
作为一个整体退出实例,因此它不适合在可以交互运行或必须从其他批处理文件调用并将控制权返回给这些批处理文件的批处理文件中使用。exit /b <code>
或exit <code>
,其中<code>
表示所需的退出代码,即指定显式退出代码,如 jazzdelightsme 的解决方案。
exit /b
没有明确的<code>
说法并没有通过通过最近执行的命令的退出代码没有cmd /c <batch-file> ... `& exit
解决方法-看到这个答案。在您的代码上下文中的其他背景信息:
奇怪的是,与外界的批处理文件的调用,而不& exit
(或call
),报表等if
,goto
,echo
,和endlocal
,甚至REM
(但是,奇怪的是,不是::
)复位退出代码cmd.exe
后报告0
-即使里面是cmd.exe
会话%ERRORLEVEL%
设置,因为它通常是,这意味着此类语句对当前%ERRORLEVEL%
值没有影响。
所以:
当你的批处理文件运行从里面 cmd.exe
,下面的命令的具体陈述,套%ERRORLEVEL%
到1
(cmd /c dir aaa
),即if
,goto
,echo
和endlocal
报表,保存该值,并%ERRORLEVEL%
结束了值1
退出批处理文件之后。
file.cmd || exit
做不工作,因为||
运营商不承认file.cmd
呼叫已经有失败的。这就是变通方法使用&
而不是的原因||
。当您的批处理文件从外部 运行cmd.exe
,并且没有使用cmd /c <batch-file> ... `& exit
(或cmd /c call <batch-file> ...
)调用时,%ERRORLEVEL%
-setting 命令cmd.exe
后面的相同语句会突然重置其自身稍后报告的退出代码0
,而不是保留批处理文件执行后%ERRORLEVEL%
价值。
[1] 或者,您可以使用 form cmd /c "<batch-file> ... & exit"
,但这需要对"
作为参数一部分的任何字符进行转义。如果没有使用 PowerShell 变量或表达式,单引号是一个选项,可以避免该问题:cmd /c '<batch-file> ... & exit'
[2]^
字符。在不加引号的参数中,像往常一样,被解释为cmd.exe
的转义字符,因此被删除。
归档时间: |
|
查看次数: |
489 次 |
最近记录: |