首页 > 解决方案 > 使用 Popen 在 python 中运行子进程并启动 /wait 时无法获取退出代码

问题描述

我正在尝试创建一个 python 脚本来启动一个新窗口并等待它完成,然后检索退出代码。所以我使用 Popenstart /wait为它创建一个单独的窗口,但这并没有正确转发退出代码。

这段代码总结了问题:

import subprocess

params = {}
params['stdout'] = subprocess.PIPE
params['stderr'] = subprocess.PIPE
params['shell'] = True

proc = subprocess.Popen('start /wait cmd /c exit 1', **params)

# This works but the above line does not
#proc = subprocess.Popen('exit 1', **params)

resultCode = proc.wait()

print(resultCode)

的文档start /wait建议它应该返回退出代码,当我手动运行它然后检查%ERRORLEVEL%它是否正确,所以我不确定我做错了什么

标签: pythonwindowscommand-linepopenexit-code

解决方案


如果通过或成功执行给定命令, CMD 的start命令总能成功。即使它被指示并最终设置为非零值,它也会成功。你可以通过运行看到这一点。如果左侧表达式成功,则运算符仅执行右侧表达式 。CreateProcessShellExecuteEx/wait%errorlevel%(start /wait exit 1) && echo success&&

要解决此问题,您可以使用!errorlevel!设置的值手动退出初始 shell start。例如:

command = 'exit 1'
shell_path = os.environ.get('ComSpec', 'cmd.exe')
start_command = 'start "" /wait {}'.format(command)
cmdline = '"{shell}" /v:on /c "({command}) & exit !errorlevel!"'.format(
          shell=shell_path, command=start_command)

proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

请注意,上述Popen调用不使用参数,因为 shell 需要使用该选项shell=True手动运行。/v:on这可以使用“!”延迟扩展环境变量 代替 ”%”。

也就是说,您不需要外壳来实现您的既定目标。只需让子进程通过传递CREATE_NEW_CONSOLE创建标志来创建一个新控制台,如下所示:

proc = subprocess.Popen(args, creationflags=subprocess.CREATE_NEW_CONSOLE,
           stdout=subprocess.PIPE, stderr=subprocess.PIPE)

推荐阅读