2015-06-19 1 views
12

Während ich die Python-Wrapper-Bibliothek für Android Debug Bridge (ADB) entwickle, verwende ich Subprozess, um adb-Befehle in der Shell auszuführen. Hier ist das vereinfachte Beispiel:Wie erhalten Sie sowohl den Rückgabecode als auch die Ausgabe vom Subprozess in Python?

import subprocess 

... 

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

Wenn Befehl ausgeführt propery exec_adb_command 0 zurück, die in Ordnung ist.

Aber einige adb-Befehle geben nicht nur "0" oder "1" zurück, sondern erzeugen auch einige Ausgaben, die ich auch abfangen möchte. adb devices zum Beispiel:

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

Ich habe bereits versucht subprocess.check_output() zu diesem Zweck, und es tut Ausgang zurück, aber nicht den Return-Code ("0" oder "1").

Idealerweise würde ich ein Tupel erhalten wollen, in dem t [0] Rückgabecode ist und t [1] die tatsächliche Ausgabe ist.

Fehle ich etwas im Subprozessmodul, das bereits solche Ergebnisse zulässt?

Danke!

Antwort

22

Popen und kommunizieren können Sie die Ausgabe und den Rückkehrcode erhalten.

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 kann auch geeignet sein, ein von Null verschiedenen Exit-Status einen CalledProcessError erhöhen wird:

from subprocess import check_output, CalledProcessError 

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

Sie müssen auch stderr umleiten die Fehlerausgabe zu speichern:

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

Übergeben Sie einfach Ihre Befehle:

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') 
+0

Than k Sie für die breite Antwort! –

+0

@ViktorMalyi, kein Problem, gern geschehen. –