我经常希望执行subprocess.check_output
的操作,即打印STDOUT,并在退出时检查返回代码为0。但是,如果有错误,我希望STDERR被打印。当查看日志文件和仅仅看到返回代码时,通常并不是很有好处。
例如:
subprocess.check_call(['ping', '-c', '1', 'github.com2'])
将产生此错误:
subprocess.CalledProcessError: Command '['ping', '-c', '1', 'github.com2']' returned non-zero exit status 2.
在这里,我们想知道为什么它失败了,在现实世界的例子中,能够看到实际错误是什么变得非常关键。因此,我发现我总是必须将这样的调用包装在这样的东西中,才能看到STDERR:
import subprocess
cmds = ['ping', '-c', '1', 'github.com2']
result = subprocess.run(cmds, stderr=subprocess.PIPE)
if result.returncode != 0:
msg = result.stderr.decode().strip()
raise subprocess.CalledProcessError(f"CALLED SUBPROCESS ERROR: Command: {' '.join(cmds)}\nReturn code {result.returncode}\nSTDERR: {msg}\n")
通过上面的内容,我们可以看到STDERR是:
ping: github.com2: Temporary failure in name resolution
我觉得一定有一个内置的方式使用子进程,但无法弄清楚。
我猜这是不可能的,因为CalledSubprocessError不使用STDERR是异常的字符串版本:
class CalledProcessError(SubprocessError):
"""Raised when run() is called with check=True and the process
returns a non-zero exit status.
Attributes:
cmd, returncode, stdout, stderr, output
"""
def __init__(self, returncode, cmd, output=None, stderr=None):
self.returncode = returncode
self.cmd = cmd
self.output = output
self.stderr = stderr
def __str__(self):
if self.returncode and self.returncode < 0:
try:
return "Command '%s' died with %r." % (
self.cmd, signal.Signals(-self.returncode))
except ValueError:
return "Command '%s' died with unknown signal %d." % (
self.cmd, -self.returncode)
else:
return "Command '%s' returned non-zero exit status %d." % (
self.cmd, self.returncode)
@property
def stdout(self):
"""Alias for output attribute, to match stderr"""
return self.output
@stdout.setter
def stdout(self, value):
# There's no obvious reason to set this, but allow it anyway so
# .stdout is a transparent alias for .output
self.output = value
https://stackoverflow.com/questions/71406698
复制相似问题