Подтвердить что ты не робот

Проверьте код возврата команды, когда подпроцесс вызывает исключение CalledProcessError

Я хочу захватить поток stdout команды оболочки в python (3) script и в то же время иметь возможность проверить код возврата команды оболочки, если он возвращает ошибку ( то есть, если его код возврата не равен 0).

subprocess.check_output представляется подходящим методом для этого. На странице subprocess man:

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'

Я признаю, что не знаю, где я ошибаюсь.

4b9b3361

Ответ 1

Чтобы получить как выход процесса, так и возвращенный код:

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)

Ответ 2

Скорее всего, мой ответ больше не уместен, но я думаю, что он может быть решен с помощью этого кода:

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