即使发生错误,Python subprocess.Popen.wait() 也会返回 0

Posted

技术标签:

【中文标题】即使发生错误,Python subprocess.Popen.wait() 也会返回 0【英文标题】:Python subprocess.Popen.wait() returns 0 even though an error occured 【发布时间】:2012-12-08 07:45:23 【问题描述】:

我正在通过 Python 的子进程模块运行命令行实用程序。我使用命令行参数和 stdout=subprocess.PIPE 创建了一个 subprocess.Popen() 对象,然后我使用 subprocess.wait() 等待任务完成并返回应该指示任务是否成功完成的返回码.

translate = subprocess.Popen(['gdal_translate', '-of', 'HFA', 'inDataset', 'outDataset'], stdout=subprocess.PIPE)
if translate.wait() == 0: print "Success"
else: print "Fail - %s" % translate.stdout.read()

如果我在 windows 命令提示符下运行我的脚本,我可以看到 gdal_translate 提供的消息,他们说有错误导致进程失败,但我的脚本仍然打印“成功”。

如果返回码始终为 0,我如何检查命令行实用程序报告的错误?

【问题讨论】:

如果直接在终端运行命令,它的退出码是什么? 如何在终端中查看退出代码?这是我收到的错误消息的示例:ERROR 1: path\to\dataset, band 1: IReadBlock failed at X offset 100, Y offset 331 在 Windows 上? echo %errorlevel%,我想。在 bash 中,它将是 echo $? 【参考方案1】:

您可能会得到输出错误,但返回码仍然为零。在您的代码中,您只捕获标准输出而不是标准错误。在下面的run函数中会运行一条命令,等待执行结束,然后读取returncode标准错误和标准输出。如果标准错误有任何内容或返回码不为零,那么它将视为失败。您可以在代码中看到四个示例调用。第一个是正常的成功调用,第二个有返回码 0 但有错误输出和标准输出。第三个有一个非零返回码和错误输出,而最后一个例子有一个非零返回码,根本没有输出。

代码

from subprocess import Popen, PIPE

def run(cmd):
    print '-'*40
    print 'running:', cmd
    p = Popen(cmd, stderr=PIPE, stdout=PIPE, shell=True)
    output, errors = p.communicate()
    print [p.returncode, errors, output]
    if p.returncode or errors:
        print 'something went wrong...'

run("echo all is well")
run("echo out;echo error 1>&2")
run("this-will-fail")
run("exit 1")

输出

----------------------------------------
running: echo all is well
[0, '', 'all is well\n']
----------------------------------------
running: echo out;echo error 1>&2
[0, 'error\n', 'out\n']
something went wrong...
----------------------------------------
running: this-will-fail
[127, '/bin/sh: this-will-fail: not found\n', '']
something went wrong...
----------------------------------------
running: exit 1
[1, '', '']
something went wrong...

【讨论】:

如果程序产生足够的输出来填充管道缓冲区,您给出的代码可能会阻塞。您应该改用subprocess.communicate:docs.python.org/2/library/… @EdwardLoper 我已经更新了使用交流的答案,感谢您的评论。

以上是关于即使发生错误,Python subprocess.Popen.wait() 也会返回 0的主要内容,如果未能解决你的问题,请参考以下文章

从命令行 Python 捕获错误

Python 图像识别错误2

Python subprocess shell 编程规范

python subprocess 路径错误解决

打开Python IDLE时的错误:Subprocess Startup Error

Python错误:subprocess.CalledProcessError:命令返回非零退出状态1 [重复]