2015-06-19 6 views
12

Durante lo sviluppo della libreria wrapper python per Android Debug Bridge (ADB), sto utilizzando il sottoprocessore per eseguire comandi adb nella shell. Ecco l'esempio semplificato:Come ottenere sia il codice di ritorno sia l'output dal sottoprocesso in Python?

import subprocess 

... 

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

Se comando eseguito propery exec_adb_command restituisce 0 che è ok.

Ma alcuni comandi adb restituiscono non solo "0" o "1" ma generano anche un output che voglio catturare anche. adb devices ad esempio:

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

ho già provato subprocess.check_output() a tale scopo, e lo fa uscita ma non il codice di ritorno ("0" o "1") di ritorno.

Idealmente vorrei ottenere una tupla dove t [0] è codice di ritorno e t [1] è uscita effettiva.

Mi manca qualcosa nel modulo di sottoprocesso che consente già di ottenere questo tipo di risultati?

Grazie!

risposta

22

Popen e comunica consentiranno di ottenere l'output e il codice di ritorno.

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 possono essere adatti, un non-zero stato di uscita alzerà un 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 

È inoltre necessario reindirizzare stderr per memorizzare l'output di errore:

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

Basta passare i tuoi comandi:

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

di per la risposta ampia! –

+0

@ViktorMalyi, no prob, prego. –