Проверьте код возврата команды, когда подпроцесс вызывает исключение 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'
Я признаю, что не знаю, где я ошибаюсь.
Ответы
Ответ 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")