【发布时间】:2015-06-08 16:57:27
【问题描述】:
我遇到了一个奇怪的情况,我编写的批处理文件报告了不正确的退出状态。这是重现问题的最小示例:
bug.cmd
echo before
if "" == "" (
echo first if
exit /b 1
if "" == "" (
echo second if
)
)
echo after
如果我运行此脚本(使用 Python,但实际上在以其他方式启动时也会出现问题),我会得到以下结果:
python -c "from subprocess import Popen as po; print 'exit status: %d' % po(['bug.cmd']).wait()"
echo before
before
if "" == "" (
echo first if
exit /b 1
if "" == "" (echo second if )
)
first if
exit status: 0
请注意exit status 是如何报告为0 的,即使exit /b 1 应该是1。
现在奇怪的是,如果我删除里面的 if 子句(这应该没关系,因为无论如何都不应该执行 exit /b 1 之后的所有内容)并尝试启动它:
ok.cmd
echo before
if "" == "" (
echo first if
exit /b 1
)
echo after
我再次启动它:
python -c "from subprocess import Popen as po; print 'exit status: %d' % po(['ok.cmd']).wait()"
echo before
before
(environment) F:\pf\mm_3.0.1\RendezVous\Services\Matchmaking>if "" == "" (
echo first if
exit /b 1
)
first if
exit status: 1
现在exit status 被正确报告为1。
我不知道是什么原因造成的。嵌套if语句是否违法?
如何正确、可靠地批量发送脚本退出状态信号?
注意:调用exit 1(没有/b)不是一种选择,因为它会杀死整个解释器并阻止本地脚本的使用。
【问题讨论】:
-
就像一般实践中的注释一样,当您想要评估批处理脚本中的文字括号时,您应该双抽它们。我想知道外部批处理运行时是否将
%d' %评估为 null,并为您的内联 Python 命令产生意想不到的后果。试试print 'exit status: %%d' %% po... 等,看看是否有什么不同。 -
@rojo:在这种情况下应该没关系:我尝试在 Python shell 中启动它,但同样的事情发生了。
-
在没有 Python 的情况下无法重新创建。如果我在
cmd控制台中从您的第一个代码块运行 bug.cmd,echo %ERRORLEVEL%会显示 1。您所说的“使用 Python,但在以其他方式启动时也会出现问题” ,还有什么方法? -
@rojo 我们的构建机器表现出相同的行为,但不使用 Python 来启动脚本。我得问问他们到底用什么。话虽如此,
subprocess只是在后台调用CreateProcess,所以 Python 很可能不是问题。 -
@rojo:你是如何启动它的?如果我使用
cmd /C bug.cmd然后调用echo %errorlevel%我会重现奇怪的行为。
标签: python windows batch-file exit-code