当子进程引发CalledProcessError异常时检查命令的返回代码

25 投票
2 回答
61315 浏览
提问于 2025-04-17 18:32

我想在一个Python(3)脚本中捕获一个shell命令的stdout流,同时还想检查这个命令的返回码,以便在出错时(也就是返回码不是0的时候)能知道发生了什么。

subprocess.check_output看起来是实现这个功能的合适方法。从subprocess的手册页来看:

check_output(*popenargs, **kwargs)
    Run command with arguments and return its output as a byte string.

    If the exit code was non-zero it raises a CalledProcessError.  The
    CalledProcessError object will have the return code in the returncode
    attribute and output in the output attribute.

不过,我还是没能在命令失败时获取到返回码。我的代码是这样的:

import subprocess
failing_command=['ls', 'non_existent_dir']

try:
    subprocess.check_output(failing_command)
except:
    ret = subprocess.CalledProcessError.returncode  # <- this seems to be wrong
    if ret in (1, 2):
        print("the command failed")
    elif ret in (3, 4, 5):
        print("the command failed very much")

这段代码在处理异常的时候又抛出了一个异常:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
AttributeError: type object 'CalledProcessError' has no attribute 'returncode'

我承认我不知道哪里出了问题。

2 个回答

5

我觉得我的回答可能已经不太适用了,但我认为可以用这段代码来解决这个问题:

import subprocess
failing_command='ls non_existent_dir'

try:
    subprocess.check_output(failing_command, shell=True, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
    ret =   e.returncode 
    if ret in (1, 2):
        print("the command failed")
    elif ret in (3, 4, 5):
        print("the command failed very much")
42

要同时获取程序的输出和返回的代码:

from subprocess import Popen, PIPE

p = Popen(["ls", "non existent"], stdout=PIPE)
output = p.communicate()[0]
print(p.returncode)

subprocess.CalledProcessError 是一个类。要获取 returncode,需要使用这个异常的实例:

from subprocess import CalledProcessError, check_output

try:
    output = check_output(["ls", "non existent"])
    returncode = 0
except CalledProcessError as e:
    output = e.output
    returncode = e.returncode

print(returncode)

撰写回答