subprocess.check_output()
的输出目前看起来像这样:
CalledProcessError: Command '['foo', ...]' returned non-zero exit status 1
有没有办法获得更好的错误消息?
我希望看到stdout
和stderr
。
答案 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()
,请改用Popen
和Popen.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".