Terminate Python Subprocesses with shell=True

Your Paragraph Text

The ‘subprocess’ is a module in Python. It is used to spawn and interact with new processes. The term ‘spawn’ typically refers to the mechanism by which a new process created. It is used to connect their input/output/error pipes, and their return codes. When launching a subprocess with ‘shell=True‘, the Python script delegates command execution to the shell.

This is convenient for executing complex shell commands. It means that the command can include shell-specific features such as pipes, redirects, and variable expansions.

To terminate a Python subprocess created with shell=True, two primary methods are used: process.terminate() and process.kill(). process.terminate() sends a SIGTERM signal, requesting a graceful exit, while process.kill() sends a SIGKILL signal for immediate termination. These methods are essential for controlling long-running or unresponsive subprocesses in Python scripts.

Also read: How to check if a process is still running using Python on Linux?

Creating a Basic Subprocess with Shell=True

Let’s see one simple example of a Python ‘subprocess‘ module with ‘shell=True‘. Creating a Python script using vi editor, named example1.py.

import subprocess

command = "echo Hello, World!"
subprocess.run(command, shell=True)

Here first we import a subprocess module using the ‘import subprocess’ line. The command is a string variable and assigns the value “echo Hello, World!”. This is a simple shell command that echoes (prints) the string “Hello, World!”. The ‘subprocess.run()‘, runs the external command. The ‘command’ parameter is the command to be executed. The ‘shell=True’ allows the command to be run in the shell.

Output: To get the output use the following command:

python example1.py
Using Shell T Op

The output is ‘Hello, World!’


Terminating a Subprocess with Shell=True

We will explore how to terminate the Python subprocess launched with shell=True with two methods. The terminating process is used to send a termination signal to a running process. It is particularly useful when you want to abruptly stop the execution of a child process from your Python script.

Method 1: Terminating with process.terminate()

Steps to terminate a Python subprocess launched with shell=True using the ‘process.terminate()‘ method.

First, we will create a Python script using vi editor. In this, we will use the ‘process.terminate()‘ method to terminate a process.

Use the following command to create a Python script. We will use vi editor.

vi subprocess_eg.py

This will create a Python script. You can replace the file name with the name you want. Press ‘i’ for insert mode and start typing code.

import subprocess
process = subprocess.Popen('ls', shell=True)
process.terminate()
process.wait()
print(f"Process returned with code: {process.returncode}")

We import the subprocess module using the ‘import subprocess‘ line.

  • The ‘process = subprocess.Popen(‘ls’, shell=True)‘ line creates a new process using the ‘Popen‘ class from the subprocess module. It runs the ‘ls’ command as a subprocess.
  • The ‘ls’ command is used to list the contents in the directory. The ‘shell=True‘ is used to run the command in a shell.
  • The ‘process.terminate()‘ line is used to terminate a subprocess. The ‘terminate()‘ method sends a termination signal to the process. The ‘process.wait()‘, waits for the subprocess to terminate.
  • The ‘print(f”Process returned with code: {process.returncode}”)‘ line prints the return code of the subprocess.
  • The ‘returncode‘ attribute of the ‘Popen‘ object stores the exit code of the process.

Here it prints the exit code of the ‘ls’ command after it has been terminated or completed.

Output:

To get the output use the following command line:

python subprocess_eg.py

This command line gives the output of the subprocess_eg.py. You can replace the subprocess_eg.py with the actual name of your Python script.

Subprocesss Eg Op

The output is ‘Process returned with code: -15‘, and the return code for the ‘ls‘ command is ‘-15‘. The return code is negative, it indicates that the process was terminated by a signal. Here -15 indicates the process received the ‘SIGTERM‘ signal, which requests for termination.

Also read: Python subprocess module


Method 2: Force Termination with process.kill()

Now we will see how to terminate a Python subprocess launched with shell=True using the ‘process.kill()‘ method.

This method is similar to method 1 which is by using the process.terminate() method.
Let’s create first a Python script. In this method, we will use the ‘process.kill()’ method to terminate a subprocess. Here we will create a Python script using the vi editor named subprocess_eg1.py. Use the following command to create a Python script.

vi subprocess_eg1.py

This command creates a Python file and opens it in the vi editor.

import subprocess
process = subprocess.Popen('ps', shell=True)
process.kill()
process.wait()
print(f"Process returned with code: {process.returncode}")

Here we import the subprocess module. It runs the ‘ps’ command as a subprocess. The ‘process.kill()‘ is used to forcefully terminate a subprocess. The process.wait(), waits for the subprocess to terminate. At the end, it will print the return code of a subprocess.

Output:

Subprocesss Eg1 Op

The output is ‘Process return with code: -9‘, and the return code for the ‘ps’ command is ‘-9‘. The return code is negative, it indicates that the process was terminated by a signal. Here -9 indicates the process received the ‘SIGKILL‘ signal, which immediately terminates the subprocess without any chance to perform cleanup operations. This is a more abrupt termination compared to the ‘process.terminate()‘ method.


Summary:

Here we learned about how to terminate a Python subprocess launched with shell=True with two methods. The first method is using ‘process.terminate()’, and the second is using ‘process.kill()’. Terminating a Python subprocess launched with shell=True on Linux may be necessary in situations where you need to abruptly stop the execution of an external command or process. This could be due to unexpected conditions, errors, or if you want to enforce a timeout on the subprocess.


Reference:

https://stackoverflow.com/questions/4789837/how-to-terminate-a-python-subprocess-launched-with-shell-true