subprocess.check_output 返回码
Posted
技术标签:
【中文标题】subprocess.check_output 返回码【英文标题】:subprocess.check_output return code 【发布时间】:2014-06-18 17:10:57 【问题描述】:我正在使用:
grepOut = subprocess.check_output("grep " + search + " tmp", shell=True)
要运行终端命令,我知道我可以使用 try/except 来捕获错误,但是如何获取错误代码的值?
我在官方文档上找到了这个:
exception subprocess.CalledProcessError
Exception raised when a process run by check_call() or check_output() returns a non-zero exit status.
returncode
Exit status of the child process.
但没有给出示例,谷歌也没有帮助。
【问题讨论】:
【参考方案1】:您可以从引发的异常中获取错误代码和结果。
这可以通过returncode
和output
字段完成。
例如:
import subprocess
try:
grepOut = subprocess.check_output("grep " + "test" + " tmp", shell=True)
except subprocess.CalledProcessError as grepexc:
print("error code", grepexc.returncode, grepexc.output)
【讨论】:
谢谢你正是我想要的。但现在我想知道,有没有办法在没有尝试/例外的情况下获得返回码? IE 只是获取 check_output 的返回码,是 0 还是 1 或其他对我来说并不重要,我实际上不需要保存输出。 没问题。不幸的是,只要错误代码不为零,check_output 将始终抛出 CalledProcessError。这意味着如果您不希望程序突然终止,您将需要一个 try/except 子句。但是,如果您不关心错误代码,则可以在进入 except 子句时使用“pass”语句。【参考方案2】:有没有办法在没有尝试/例外的情况下获得返回码?
check_output
如果收到非零退出状态,则会引发异常,因为这通常意味着命令失败。即使没有错误,grep
也可能返回非零退出状态——在这种情况下,您可以使用 .communicate()
:
from subprocess import Popen, PIPE
pattern, filename = 'test', 'tmp'
p = Popen(['grep', pattern, filename], stdin=PIPE, stdout=PIPE, stderr=PIPE,
bufsize=-1)
output, error = p.communicate()
if p.returncode == 0:
print('%r is found in %s: %r' % (pattern, filename, output))
elif p.returncode == 1:
print('%r is NOT found in %s: %r' % (pattern, filename, output))
else:
assert p.returncode > 1
print('error occurred: %r' % (error,))
您不需要调用外部命令来过滤行,您可以在纯 Python 中完成:
with open('tmp') as file:
for line in file:
if 'test' in line:
print line,
如果你不需要输出;你可以使用subprocess.call()
:
import os
from subprocess import call
try:
from subprocess import DEVNULL # Python 3
except ImportError: # Python 2
DEVNULL = open(os.devnull, 'r+b', 0)
returncode = call(['grep', 'test', 'tmp'],
stdin=DEVNULL, stdout=DEVNULL, stderr=DEVNULL)
【讨论】:
【参考方案3】:Python 3.5 引入了subprocess.run()
方法。签名看起来像:
subprocess.run(
args,
*,
stdin=None,
input=None,
stdout=None,
stderr=None,
shell=False,
timeout=None,
check=False
)
返回的结果是subprocess.CompletedProcess
。在 3.5 中,您可以从执行的进程中访问args
、returncode
、stdout
和stderr
。
例子:
>>> result = subprocess.run(['ls', '/tmp'], stdout=subprocess.DEVNULL)
>>> result.returncode
0
>>> result = subprocess.run(['ls', '/nonexistent'], stderr=subprocess.DEVNULL)
>>> result.returncode
2
【讨论】:
我认为这是最新的方法。语法更加简单和直观,可能正是出于这个原因而添加的。 根据docs.python.org/3/library/subprocess.html#subprocess.run:“如果检查为真,并且进程以非零退出代码退出,则会引发 CalledProcessError 异常。该异常的属性包含参数,退出代码, 以及 stdout 和 stderr(如果它们被捕获)。”【参考方案4】:要获得输出和返回代码(不带 try/except),只需使用 subprocess.getstatusoutput(需要 Python 3)
【讨论】:
请阅读***.com/help/how-to-answer,了解如何写出好的答案。 完成。现在呢? 这不仅仅是阅读,而是关于在您的答案中实施它。 我想我只是不明白它有什么问题。请告诉我您认为应该如何改进。 你可以提供一个你提到的方法的例子。然而,你的回答让我注意到了另一种我还不知道的方法,所以无论如何它对我来说已经很有价值了。【参考方案5】:在 Python 2 中 - 使用 commands 模块:
import command
rc, out = commands.getstatusoutput("ls missing-file")
if rc != 0: print "Error occurred: %s" % out
在 Python 3 中 - 使用 subprocess 模块:
import subprocess
rc, out = subprocess.getstatusoutput("ls missing-file")
if rc != 0: print ("Error occurred:", out)
发生错误:ls: cannot access missing-file: No such file or directory
【讨论】:
以上是关于subprocess.check_output 返回码的主要内容,如果未能解决你的问题,请参考以下文章
如何编写 subprocess.check_output 的异步版本?
在 subprocess.check_output() 中抑制 stderr
Python subprocess.check_output()
当父进程死亡时,如何杀死使用 subprocess.check_output() 创建的 python 子进程?