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

19 投票
4 回答
7681 浏览
提问于 2025-04-18 10:59

现在,subprocess.check_output() 的输出看起来是这样的:

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

有没有办法让错误信息更清晰一些呢?

我想看到 stdoutstderr 的内容。

4 个回答

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".
6

不要使用 check_output(),而是使用 PopenPopen.communicate()

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

这里的 output 是来自 stdout 的数据,而 errors 是来自 stderr 的数据。

14

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" <

解释

来自 check_output 的文档:

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

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可以帮助你找到问题的根源。

撰写回答