subprocess.check_output():失败时显示输出
现在,subprocess.check_output()
的输出看起来是这样的:
CalledProcessError: Command '['foo', ...]' returned non-zero exit status 1
有没有办法让错误信息更清晰一些呢?
我想看到 stdout
和 stderr
的内容。
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()
,而是使用 Popen
和 Popen.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可以帮助你找到问题的根源。