subprocess.check_output():显示失败时的输出

时间:2014-06-25 08:24:00

标签: python subprocess

subprocess.check_output()的输出目前看起来像这样:

CalledProcessError: Command '['foo', ...]' returned non-zero exit status 1

有没有办法获得更好的错误消息?

我希望看到stdoutstderr

4 个答案:

答案 0 :(得分:7)

STDERR重定向到STDOUT

来自解释器的

示例

>>> try:
...   subprocess.check_output(['ls','-j'], stderr=subprocess.STDOUT)
... except subprocess.CalledProcessError as e:
...   print('error>', e.output, '<')
...

抛出

error> b"ls: invalid option -- 'j'\nTry `ls --help' for more information.\n" <

<强> Explantion

来自check_output文档:

  

要在结果中也捕获标准错误,请使用   stderr=subprocess.STDOUT

答案 1 :(得分:6)

请勿使用check_output(),请改用PopenPopen.communicate()

>>> proc = subprocess.Popen(['cmd', '--optional-switch'])
>>> output, errors = proc.communicate()

此处output是来自stdout的数据,而errors是来自stderr的数据。

答案 2 :(得分:2)

由于我不想编写更多代码,只是为了获得良好的错误消息,所以我写了subx

从文档中

  

subprocess.check_output()与subx.call()

     

查找,比较,思考和决定哪种信息对您有更大帮助。

     

subprocess.check_output()::

CalledProcessError: Command '['cat', 'some-file']' returned non-zero exit status 1
     

sub.call()::

SubprocessError: Command '['cat', 'some-file']' returned non-zero exit status 1:
stdout='' stderr='cat: some-file: No such file or directory'
     

...尤其是当代码在生产环境中失败时,   重现错误并非易事,subx可以致电帮助您发现   故障原因。

答案 3 :(得分:1)

我认为使用sys.excepthook的完美方案!您只需要在if语句中过滤想要设置的格式即可。使用此解决方案,它将覆盖代码的每个异常,而不必重新定义所有内容!

#!/usr/bin/env python
import sys
import subprocess

# Create the exception handler function
def my_excepthook(type, value, traceback):
    # Check if the exception type name is CalledProcessError
    if type.__name__ == "CalledProcessError":
        # Format the error properly
        sys.stderr.write("Error: " + type.__name__ + "\nCommand: " + value.cmd + "\nOutput: " + value.output.strip())
    # Else we format the exception normally
    else:
        sys.stderr.write(str(value))

# We attach every exceptions to the function my_excepthook
sys.excepthook = my_excepthook

# We duplicate the exception
subprocess.check_output("dir /f",shell=True,stderr=subprocess.STDOUT)

您可以根据需要修改输出,这是实际的输出:

Error: CalledProcessError
Command: dir /f
Output: Invalid switch - "f".