The python subprocess module comes with as standard when python is installed and recommend to be used over other modules when running system commands. This is true for Unix, Linux and Windows.
I am a big fan of ArchLinux and tend to run all my stuff on the BlackArch version. You can find my install guide for Arch with the BlackArch repositories on my blog.
Things to be aware of,
Since it was added in python 3.5, subprocess.run is the recommended way to run all commands via the subprocess module.
If shell is True the specified command will be executed through the shell. This can be useful if you are using Python primarily for the enhanced control flow it offers over most system shells and still want convenient access to other shell features such as shell pipes, filename wildcards, environment variable expansion, and expansion of
~ to a user’s home directory.
There are some challenges to using shell=True
Take the following command where we set “shell=True”
subprocess.run(['ls', '-l', '/'],shell=True)
In this case the command ‘ls -l /’ is request to be run and so the command + the arguments are supplied in a sequence (list), The first item specifies the command string, and any additional items will be treated as additional arguments to the shell itself. So the output of this command is just from ‘ls’ and the ‘-l’ and ‘/’ part is added to the shell. i.e. in this case the shell would be launched with ‘sh -l /’.
In order to get it to work as you expect you have to run with with all the options and command together as a string.
subprocess.run('ls -l /', shell=True)
Should you use Shell=True
I don’t recommend it unless absolutely needed. There are also some security concerns about it.
However, in the examples below I will mix it up a bit so you can experience the usage of both.
As this is all in python3 when the results of the command are captured in a variable they will be in byte format as default. It is needed to to convert them to a string with the “.decode(‘utf-8’) method.
Subprocess Code Examples
Run a process
In this example the returned data will not be captured and the output is just returned to the output to the screen.
Run a process in a shell
Running a process inside a shell gives you access to shell variables and functions. However most of these can gotten from other modules such as “os”.
subprocess.run('ls -l', shell=True])
Get the return code from a Process
Return codes are important if we only care about if the command was successful or not.
return_code = subprocess.run('ls -l',shell=True,check=True) print(return_code)
Capture the command results.
In order to capture the command results into a variable you need to set the “capture_output” value to be true. This returns a Class of type “CompletedProcess” which has multiple values. You can pull out the stout values by accessing the stout value in the class. This value is in binary format so you need to convert it to a string in order to be useable.
cmd_output = subprocess.run('ls -l /', shell=True,capture_output=True) print(cmd_output.stdout.decode())
You can find all my code for this post on my github page. Any comments or queries let me know in the comment section below.