What’s a good equivalent to subprocess.check_call that returns the contents of stdout?

I’d like a good method that matches the interface of subprocess.check_call — ie, it throws CalledProcessError when it fails, is synchronous, &c — but instead of returning the return code of the command (if it even does that) returns the program’s output, either only stdout, or a tuple of (stdout, stderr).

Does somebody have a method that does this?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Python 2.7+

from subprocess import check_output as qx

Python < 2.7

From subprocess.py:

import subprocess
def check_output(*popenargs, **kwargs):
    if 'stdout' in kwargs:
        raise ValueError('stdout argument not allowed, it will be overridden.')
    process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs)
    output, unused_err = process.communicate()
    retcode = process.poll()
    if retcode:
        cmd = kwargs.get("args")
        if cmd is None:
            cmd = popenargs[0]
        raise subprocess.CalledProcessError(retcode, cmd, output=output)
    return output

class CalledProcessError(Exception):
    def __init__(self, returncode, cmd, output=None):
        self.returncode = returncode
        self.cmd = cmd
        self.output = output
    def __str__(self):
        return "Command '%s' returned non-zero exit status %d" % (
            self.cmd, self.returncode)
# overwrite CalledProcessError due to `output` keyword might be not available
subprocess.CalledProcessError = CalledProcessError

See also Capturing system command output as a string for another example of possible check_output() implementation.

Method 2

I can not get formatting in a comment, so this is in response to J.F. Sebastian’s answer

I found this very helpful so I figured I would add to this answer. I wanted to be able to work seamlessly in the code without checking the version. This is what I did…

I put the code above into a file called ‘subprocess_compat.py’. Then in the code where I use subprocess I did.

import sys
if sys.version_info < (2, 7):
    import subprocess_compat
    subprocess.check_output = subprocess_compat.check_output

Now anywhere in the code I can just call ‘subprocess.check_output’ with the params I want and it will work regardless of which version of python I am using.

Method 3

After I read this twice, I realized it’s ten years old and most answers apply to the now deprecated python2.7 rather than python3.

Now that we are – or should be – on python3, it seems that the best option for python >= 3.7 is to use the following as is mentioned in multiple comments:

result = subprocess.run(..., check=True, capture_output=True)

To save you searching for more details, I recommend an answer I found with wonderful detail by SethMMorton in an answer to “How to suppress or capture the output of subprocess.run()?” As described there, you can access stdout, stderr directly as:

print(result.stdout)
print(result.stderr)

If you need to support Python 3.6:

You can however easily “emulate” this by setting both stdout and stderr to PIPE:

from subprocess import PIPE

subprocess.run(["ls", "-l", "/dev/null"], stdout=PIPE, stderr=PIPE)

This info is from
Willem Van Onsem‘s answer to a related question.

I tend to go straight to https://docs.python.org/3/library/subprocess.html to refresh my memory on general subprocess things. (The SO examples are often easier for me to access quickly though.)

Method 4

This function returns terminal output in the form of list of string.

import subprocess,sys
def output(cmd):
    cmd_l = cmd.split()
    output = subprocess.Popen(cmd_l, stdout=subprocess.PIPE).communicate()[0]
    output = output.decode("utf-8")
    return (output)


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x