Running Processes in Python with the Subprocess Module
To execute processes in Python, you can use the os.system and subprocess modules. In this post, we will become familiar with the subprocess module.
Take a look at this example
| |
The above code executes ls -l command in the operating system.
Popen initiates the execution of the command, but it does not wait for the process to finish. This is where the communicate method comes in, which waits for the process to complete.
The communicate method takes a timeout parameter. If the process takes longer than this value, a TimeoutExpired error is raised.
To capture the output and potential errors of the command, you should use stdout=PIPE and stderr=PIPE.
| |
stdout contains the process output, and stderr contains the process error when there is an error.
For example, if you run ls, stdout will contain the list of files and directories in the current path, and stderr will be empty. However, if you run ls -XXXX, where XXXX is an invalid option, stdout will be empty, and stderr will contain the following
| |
To merge stderr into stdout, use stderr=STDOUT.
| |
To ensure the process completion, you can use the wait method, which returns only the exit code.
| |
To check the exit code of a command in Linux, you can use:
| |
With Popen, you can change the current directory for the command to be executed
| |
You can also set environment variables
| |
To terminate a process, you can use the terminate and kill methods. terminate sends SIGKILL signal to the process and kill sends SIGKILL signal. If you run into a timeout, you can catch TimeoutExpired and use kill to ensure termination.
| |
By default, Popen takes the program name and your desired switches in the form of a list. You can use shlex to convert your command into a list for better readability.
| |
If you want to execute a command like ps aux | grep x, you might think of something like
| |
But that doesn’t work because the inputs after the first value (ps in this case) should be flags or switches not a pipe | operator
there are two solutions
First
| |
In this way the input of the first command is set as stdin of the second command
Second
| |
However, using shell=True is not secure and may lead to issues with process termination. It is recommended to use the first solution for better security.
Capture output like a stream
To capture the process output as a stream, you can use a context manager
| |
Make sure to read the documentation for the subprocess module for more information.