Retrieving the output of [duplicate] – Dev

The best answers to the question “Retrieving the output of [duplicate]” in the category Dev.


How can I get the output of a process run using

Passing a StringIO.StringIO object to stdout gives this error:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/", line 444, in call
    return Popen(*popenargs, **kwargs).wait()
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/", line 588, in __init__
    errread, errwrite) = self._get_handles(stdin, stdout, stderr)
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/", line 945, in _get_handles
    c2pwrite = stdout.fileno()
AttributeError: StringIO instance has no attribute 'fileno'


Output from should only be redirected to files.

You should use subprocess.Popen() instead. Then you can pass subprocess.PIPE for the stderr, stdout, and/or stdin parameters and read from the pipes by using the communicate() method:

from subprocess import Popen, PIPE

p = Popen(['program', 'arg1'], stdin=PIPE, stdout=PIPE, stderr=PIPE)
output, err = p.communicate(b"input data that is passed to subprocess' stdin")
rc = p.returncode

The reasoning is that the file-like object used by must have a real file descriptor, and thus implement the fileno() method. Just using any file-like object won’t do the trick.

See here for more info.


If you have Python version >= 2.7, you can use subprocess.check_output which basically does exactly what you want (it returns standard output as string).

Simple example (linux version, see note):

import subprocess

print subprocess.check_output(["ping", "-c", "1", ""])

Note that the ping command is using linux notation (-c for count). If you try this on Windows remember to change it to -n for same result.

As commented below you can find a more detailed explanation in this other answer.


I have the following solution. It captures the exit code, the stdout, and the stderr too of the executed external command:

import shlex
from subprocess import Popen, PIPE

def get_exitcode_stdout_stderr(cmd):
    Execute the external command and get its exitcode, stdout and stderr.
    args = shlex.split(cmd)

    proc = Popen(args, stdout=PIPE, stderr=PIPE)
    out, err = proc.communicate()
    exitcode = proc.returncode
    return exitcode, out, err

cmd = "..."  # arbitrary external command, e.g. "python"
exitcode, out, err = get_exitcode_stdout_stderr(cmd)

I also have a blog post on it here.

Edit: the solution was updated to a newer one that doesn’t need to write to temp. files.


For python 3.5+ it is recommended that you use the run function from the subprocess module. This returns a CompletedProcess object, from which you can easily obtain the output as well as return code.

from subprocess import PIPE, run

command = ['echo', 'hello']
result = run(command, stdout=PIPE, stderr=PIPE, universal_newlines=True)
print(result.returncode, result.stdout, result.stderr)