当 运行 在 python 中使用 Popen 进行子处理并启动 /wait 时无法获取退出代码

Cannot get exit code when running subprocesses in python using Popen and start /wait

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

这段代码总结了问题:

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 的文档建议它应该 return 退出代码,当我手动 运行 然后检查 %ERRORLEVEL% 它看起来正确,所以我我不确定我做错了什么

正在使用

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

而不是你的 start /wait returns resultCode 中的错误代码 1。

按此问答逻辑:CALL command vs. START with /WAIT option

我的猜测是,区别在于 start /wait 不与同一环境共享变量,而 call 是。

如果通过 CreateProcessShellExecuteEx 成功执行给定命令,

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

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

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=True 参数,因为 shell 需要使用 /v:on 选项手动 运行。这允许延迟扩展环境变量,使用“!”而不是“%”。

就是说,对于您声明的 objective,您不需要 shell。只需让子进程通过传递 CREATE_NEW_CONSOLE 创建标志来创建一个新的控制台,如下所示:

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