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

Как получить код возврата и выход из подпроцесса в Python?

При разработке библиотеки оболочки python для Android Debug Bridge (ADB) я использую подпроцесс для выполнения команд adb в оболочке. Вот упрощенный пример:

import subprocess

...

def exec_adb_command(adb_command):
    return = subprocess.call(adb_command)

Если команда выполнена правильно, exec_adb_command возвращает 0, это нормально.

Но некоторые команды adb возвращают не только "0" или "1", но также генерируют некоторый вывод, который я хочу также поймать. adb, например:

D:\git\adb-lib\test>adb devices
List of devices attached
07eeb4bb        device

Я уже пробовал subprocess.check_output() для этой цели, и он возвращает результат, но не код возврата ( "0" или "1" ).

В идеале я хотел бы получить кортеж, где t [0] - это код возврата, а t [1] - фактический вывод.

Я пропустил что-то в модуле подпроцесса, который уже позволяет получить такие результаты?

Спасибо!

4b9b3361

Ответ 1

Popen и связь позволят вам получить выходные данные и код возврата.

from subprocess import Popen,PIPE,STDOUT

out = Popen(["adb", "devices"],stderr=STDOUT,stdout=PIPE)

t = out.communicate()[0],out.returncode
print(t)
('List of devices attached \n\n', 0)

check_output также может быть подходящим, статус ненулевого выхода повысит CalledProcessError:

from subprocess import check_output, CalledProcessError

try:
    out = check_output(["adb", "devices"])
    t = 0, out
except CalledProcessError as e:
    t = e.returncode, e.message

Вам также необходимо перенаправить stderr, чтобы сохранить вывод ошибки:

from subprocess import check_output, CalledProcessError

from tempfile import TemporaryFile

def get_out(*args):
    with TemporaryFile() as t:
        try:
            out = check_output(args, stderr=t)
            return  0, out
        except CalledProcessError as e:
            t.seek(0)
            return e.returncode, t.read()

Просто передайте свои команды:

In [5]: get_out("adb","devices")
Out[5]: (0, 'List of devices attached \n\n')

In [6]: get_out("adb","devices","foo")
Out[6]: (1, 'Usage: adb devices [-l]\n')