Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get both return code and output from subprocess in Python? [duplicate]

While developing python wrapper library for Android Debug Bridge (ADB), I'm using subprocess to execute adb commands in shell. Here is the simplified example:

import subprocess

...

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

If command executed propery exec_adb_command returns 0 which is OK.

But some adb commands return not only "0" or "1" but also generate some output which I want to catch also. adb devices for example:

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

I've already tried subprocess.check_output() for that purpose, and it does return output but not the return code ("0" or "1").

Ideally I would want to get a tuple where t[0] is return code and t[1] is actual output.

Am I missing something in subprocess module which already allows to get such kind of results?

Thanks!

like image 602
Viktor Malyi Avatar asked Jun 19 '15 12:06

Viktor Malyi


People also ask

How do I get the output of a subprocess call?

communicate() #Another way to get output #output = subprocess. Popen(args,stdout = subprocess. PIPE). stdout ber = raw_input("search complete, display results?") print output #... and on to the selection process ...

What does Popen return Python?

Description. Python method popen() opens a pipe to or from command. The return value is an open file object connected to the pipe, which can be read or written depending on whether mode is 'r' (default) or 'w'. The bufsize argument has the same meaning as in open() function.

What is the return type of subprocess Check_output?

CalledProcessError Exception raised when a process run by check_call() or check_output() returns a non-zero exit status. returncode Exit status of the child process.


1 Answers

Popen and communicate will allow you to get the output and the return code.

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 may also be suitable, a non-zero exit status will raise a 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 

You also need to redirect stderr to store the error output:

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

Just pass your commands:

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') 
like image 98
Padraic Cunningham Avatar answered Sep 20 '22 12:09

Padraic Cunningham