Python provides a lot of modules for different operating system related operations. Running external command or shell command is a very popular Python developer. We can call Linux or Windows commands from python code or script and use output.
Import os Module
We can use system()
function in order to run a shell command in Linux and Windows operating systems. system()
is provided by os
Module. So we will load this module like below.
import os
Run Command with system Function
After loading os
module we can use system()
function by providing the external command we want to run. In this example, we will run ls
command which will list current working directory content.
import os os.system('ls')

Import subprocess Module
Another alternative for running an external shell command is subprocess
module. This module provides process-related functions. We will use call()
function but first, we need to load subprocess
module.
import subprocess
Run Command with call Function
We will use call()
function which will create a separate process and run provided command in this process. In this example, we will create a process for ls
command. We should provide the exact path of the binary we want to call.
import subprocess subprocess.call("/bin/ls")

Provide Parameters To The Command
We may need to provide parameters to the command we will call. We will provide a list where this list includes command or binary we will call and parameters as list items. In this example, we will call ls
for path /etc/
with the -l
parameter.
subprocess.call(['/bin/ls','-l','/etc'])

Save Command Output To A Variable
We may need to save the command output to a variable or a file. We will put the output variable named o
like below. We will use read()
function of popen()
returned object. read() will provide the whole output as a single string.
o=os.popen('ls').read() print(o)

Save Command Output Line By Line
Some commands execution can create a lot of outputs that can consist of multiple lines. Alternatively, we can save these command outputs line by line by using the readlines()
function. Also, we can iterate over the readlines() function to read output line by line. Below we will execute the ls
command which will produce multiple lines output. Then we will access these output which is saved into lines
in an array or list fashion.
import os lines = os.popen('ls').readlines() print(lines[0]) #aiohttp-2.3.10-cp36-cp36m-manylinux1_x86_64.whl print(lines[1]) #aiohttp_cors-0.5.3-py3-none-any.whl print(lines[2]) #allclasses.html print(lines[3]) #allclasses-index.html print(lines[4]) #allpackages-index.html print(lines[5]) #a.out

Specify the Standard Input, Output, Error Pipe/Variables
By default, the output of the executed command is returned as a string with the Popen() function. Alternatively, we can specify pipes or variables to store the input and output pipes for the executed command. In the following example, we will use stdout
and stderr
variables to store standard output and standard error. Popen() function will create an instance where communicate()
function will return the standard output and standard error. This can be useful for commands running for long times where we need output interactively.
import subprocess c = subprocess.Popen(['ls','-l','.'], stdout = subprocess.PIPE, stderr = subprocess.PIPE) stdout, stderr = c.communicate() print(stdout) print(stderr)

os.system() vs subprocess.run() vs subprocess.Popen()
As we can see Python provides a lot of functions in order to run and execute system commands. But there are some differences during the usage of them and provides different features. Below we will compare and explain the differences and similarities of these commands.

- If we require parsed arguments the os.system() function can not be used but subprocess.run() and subprocess.Popen() can be easily used.
- If the need communication during the execution of the command with the standard input and standard output we should use subprocess.Popen() and subprocess.run() function.
In general, we can see that os.system() function provides very basic and practical usage where subprocess.run() and subprocess.Popen() provides more advanced usage with features.
I find the subprocess command much more intuitive when called with a string.split().
subprocess.call( “/bin/ls -l /etc “.split())
Thanks for your suggestion. I will update post.
well done, you just re-introduced a bug with spaces in filenames 🙂