subprocess.check_output 返回代码

81 投票
6 回答
156157 浏览
提问于 2025-04-18 05:05

我正在使用:

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.

但是里面没有给出例子,谷歌也没能帮上忙。

6 个回答

2

在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: 无法访问缺失的文件:没有这样的文件或目录

4

要同时获取输出和返回代码(不需要使用try/except),你只需使用 subprocess.getstatusoutput 这个方法(需要Python 3)。

37

有没有办法在不使用try/except的情况下获取返回码?

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)
50

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
98

你可以从抛出的异常中获取错误代码和结果。

这可以通过两个字段来实现,分别是 returncodeoutput

举个例子:

import subprocess

try:
    grepOut = subprocess.check_output("grep " + "test" + " tmp", shell=True)                       
except subprocess.CalledProcessError as grepexc:                                                                                                   
    print("error code", grepexc.returncode, grepexc.output)

撰写回答