I want to write a function that will execute a shell command and return its output as a string, no matter, is it an error or success message. I just want to get the same result that I would have gotten with the command line.
What would be a code example that would do such a thing?
For example:
def run_command(cmd):
# ??????
print run_command('mysqladmin create test -uroot -pmysqladmin12')
# Should output something like:
# mysqladmin: CREATE DATABASE failed; error: 'Can't create database 'test'; database exists'
Best Solution
In all officially maintained versions of Python, the simplest approach is to use the
subprocess.check_outputfunction:check_outputruns a single program that takes only arguments as input.1 It returns the result exactly as printed tostdout. If you need to write input tostdin, skip ahead to therunorPopensections. If you want to execute complex shell commands, see the note onshell=Trueat the end of this answer.The
check_outputfunction works in all officially maintained versions of Python. But for more recent versions, a more flexible approach is available.Modern versions of Python (3.5 or higher):
runIf you're using Python 3.5+, and do not need backwards compatibility, the new
runfunction is recommended by the official documentation for most tasks. It provides a very general, high-level API for thesubprocessmodule. To capture the output of a program, pass thesubprocess.PIPEflag to thestdoutkeyword argument. Then access thestdoutattribute of the returnedCompletedProcessobject:The return value is a
bytesobject, so if you want a proper string, you'll need todecodeit. Assuming the called process returns a UTF-8-encoded string:This can all be compressed to a one-liner if desired:
If you want to pass input to the process's
stdin, you can pass abytesobject to theinputkeyword argument:You can capture errors by passing
stderr=subprocess.PIPE(capture toresult.stderr) orstderr=subprocess.STDOUT(capture toresult.stdoutalong with regular output). If you wantrunto throw an exception when the process returns a nonzero exit code, you can passcheck=True. (Or you can check thereturncodeattribute ofresultabove.) When security is not a concern, you can also run more complex shell commands by passingshell=Trueas described at the end of this answer.Later versions of Python streamline the above further. In Python 3.7+, the above one-liner can be spelled like this:
Using
runthis way adds just a bit of complexity, compared to the old way of doing things. But now you can do almost anything you need to do with therunfunction alone.Older versions of Python (3-3.4): more about
check_outputIf you are using an older version of Python, or need modest backwards compatibility, you can use the
check_outputfunction as briefly described above. It has been available since Python 2.7.It takes takes the same arguments as
Popen(see below), and returns a string containing the program's output. The beginning of this answer has a more detailed usage example. In Python 3.5+,check_outputis equivalent to executingrunwithcheck=Trueandstdout=PIPE, and returning just thestdoutattribute.You can pass
stderr=subprocess.STDOUTto ensure that error messages are included in the returned output. When security is not a concern, you can also run more complex shell commands by passingshell=Trueas described at the end of this answer.If you need to pipe from
stderror pass input to the process,check_outputwon't be up to the task. See thePopenexamples below in that case.Complex applications and legacy versions of Python (2.6 and below):
PopenIf you need deep backwards compatibility, or if you need more sophisticated functionality than
check_outputorrunprovide, you'll have to work directly withPopenobjects, which encapsulate the low-level API for subprocesses.The
Popenconstructor accepts either a single command without arguments, or a list containing a command as its first item, followed by any number of arguments, each as a separate item in the list.shlex.splitcan help parse strings into appropriately formatted lists.Popenobjects also accept a host of different arguments for process IO management and low-level configuration.To send input and capture output,
communicateis almost always the preferred method. As in:Or
If you set
stdin=PIPE,communicatealso allows you to pass data to the process viastdin:Note Aaron Hall's answer, which indicates that on some systems, you may need to set
stdout,stderr, andstdinall toPIPE(orDEVNULL) to getcommunicateto work at all.In some rare cases, you may need complex, real-time output capturing. Vartec's answer suggests a way forward, but methods other than
communicateare prone to deadlocks if not used carefully.As with all the above functions, when security is not a concern, you can run more complex shell commands by passing
shell=True.Notes
1. Running shell commands: the
shell=TrueargumentNormally, each call to
run,check_output, or thePopenconstructor executes a single program. That means no fancy bash-style pipes. If you want to run complex shell commands, you can passshell=True, which all three functions support. For example:However, doing this raises security concerns. If you're doing anything more than light scripting, you might be better off calling each process separately, and passing the output from each as an input to the next, via
Or
The temptation to directly connect pipes is strong; resist it. Otherwise, you'll likely see deadlocks or have to do hacky things like this.