- How to Run a Shell Command from Python and Get The Output?
- Get output from shell command using subprocess
- Python: execute shell commands (and get the output) with the os package
- Execute shell commands using the os package
- Execute shell commands and get the output using the os package
- Pipe output from shell command to a python script
- 7 Answers 7
How to Run a Shell Command from Python and Get The Output?
In Python, often you may want to execute linux command and get the output of the command as string variable. There are multiple ways to execute shell command and get output using Python. A naive way to do that is to execeute the linux command, save the output in file and parse the file.
import os cmd = 'wc -l my_text_file.txt > out_file.txt' os.system(cmd)
Get output from shell command using subprocess
A better way to get the output from executing a linux command in Python is to use Python module “subprocess”. Here is an example of using “subprocess” to count the number of lines in a file using “wc -l” linux command.
Let us first import the subprocess module
# import subprocess library >import subprocess
Launch the shell command that we want to execute using subprocess.Popen function. The arguments to this command is the shell command as a list and specify output and error.
>out = subprocess.Popen(['wc', '-l', 'my_text_file.txt'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
The output from subprocess.Popen is subprocess.Popen object. And this object has number of methods associated with it and we will be using communicate() method to get the standard output and error in case as a tuple.
Here standard output contains the result from wc -l command and the stderr contains None as there are no errors.
>stdout,stderr = out.communicate() >print(stdout) 3503 my_text_file.txt >print(stderr) None
We can then parse the stdout to get the result from shell command in Python, the way we want . For example, if we just want the number of lines in the file, we split the stdout
Python: execute shell commands (and get the output) with the os package
This article is part of a two-part series related to running shell commands from within Python.
Execute shell commands using the os package
The most straightforward solution to running shell commands via Python is simply by using the system method of the os package. The os package “provides a portable way of using operating system dependent functionality.” The system method executes a string as a command in a subshell, which basically is an independent instance of the command processor of your operating system. For Windows, commands will be run using cmd.exe, for Linux this will be Bash, Mac will use Bash or Z shell.
The following code will open a subshell, run the command, and return the process exit code — a 0 (zero) if the command has run successfully, other numbers mean something has gone wrong (see Linux and Windows).
import os os.system('echo "Hello World!"')
Execute shell commands and get the output using the os package
Sometimes, you’re not only interested in running shell commands, but you’d also like to know what printed output is. The os package also has a solution for this: the popen method. This method opens a pipe into the command, which is used to transfer its output to a Python variable.
The following code will once again open a subshell and run the command, but instead of returning the process exit code, it will return the command output. If you ‘d like to remove the trailing nextline (\n), you can use the strip method
output_stream = os.popen('echo "Hello World!"') output_stream.read()
- If the command passed to the shell generates errors, it will only return two single quotes.
- If you would like to know if a command completed successfully, you can access the process exit code using the close method. Like this:
output_stream = os.popen('non-existing-command') output_stream.close()
The popen method of the os package uses the subprocess module. So instead of using popen, you might as well interface with the subprocess module directly. We discuss this in the next article.
Pipe output from shell command to a python script
I want to run a mysql command and set the output of that to be a variable in my python script. Here is the shell command I’m trying to run:
$ mysql my_database --html -e "select * from limbs" | ./script.py
#!/usr/bin/env python import sys def hello(variable): print variable
7 Answers 7
You need to read from stdin to retrieve the data in the python script e.g.
#!/usr/bin/env python import sys def hello(variable): print variable data = sys.stdin.read() hello(data)
If all you want to do here is grab some data from a mysql database and then manipulate it with Python I would skip piping it into the script and just use the Python MySql module to do the SQL query.
It looks like the shebang is important, which is why none of the other examples worked. Without it, it will just hang forever instead.
If you want your script to behave like many unix command line tools and accept a pipe or a filename as first argument, you can use the following:
#!/usr/bin/env python import sys # use stdin if it's full if not sys.stdin.isatty(): input_stream = sys.stdin # otherwise, read the given filename else: try: input_filename = sys.argv[1] except IndexError: message = 'need filename as first argument if stdin is not full' raise IndexError(message) else: input_stream = open(input_filename, 'rU') for line in input_stream: print(line) # do something useful with each line
When you pipe the output of one command to a pytho script, it goes to sys.stdin. You can read from sys.stdin just like a file. Example:
import sys print sys.stdin.read()
This program literally outputs its input.
+1 for mentioning «just like a file», which will hopefully lead the OP to realize he can also do things like «for line in sys.stdin:», etc.
Since this answer pops up on Google at the top when searching for piping data to a python script , I’d like to add another method, which I have found in [J. Beazley’s Python Cookbook][1] after searching for a less ‘gritty’ aproach than using sys . IMO, more pythonic and self-explanatory even to new users.
import fileinput with fileinput.input() as f_input: for line in f_input: print(line, end='')
This approach also works for commands structured like this:
$ ls | ./filein.py # Prints a directory listing to stdout. $ ./filein.py /etc/passwd # Reads /etc/passwd to stdout. $ ./filein.py < /etc/passwd # Reads /etc/passwd to stdout.
If you require more complex solutions, you can compine argparse and fileinput [as shown in this gist by martinth][2]:
import argparse import fileinput if __name__ == '__main__': parser = ArgumentParser() parser.add_argument('--dummy', help='dummy argument') parser.add_argument('files', metavar='FILE', nargs='*', help='files to read, if empty, stdin is used') args = parser.parse_args() # If you would call fileinput.input() without files it would try to process all arguments. # We pass '-' as only file when argparse got no files which will cause fileinput to read from stdin for line in fileinput.input(files=args.files if len(args.files) > 0 else ('-', )): print(line)
[1]: https://library.oreilly.com/book/0636920027072/python-cookbook-3rd-edition/199.xhtml?ref=toc#_accepting_script_input_via_redirection_pipes_or_input_files [2]: https://gist.github.com/martinth/ed991fb8cdcac3dfadf7