SIGTERM vs SIGKILL - Explained with Python

Introduction
Hello pals,
In this article i want to help you fully understand why you should choose the right signal to kill a process in Linux, explaining it in a simple way so you won’t feel the need to look elsewhere for the explanation.
Many Linux newcomers wonder what the difference is between the commands below, even though both of them kill a process.
kill 1234
kill -9 1234
Yes, they both kill a process.
So choosing one or the other would supposedly be the same, right?
I’ve got bad news for you, my friend: not really 😰
What Are Linux Signals?
In simple terms, signals are essentially events that the operating system uses to notify a program about something that has happened.
Each signal has an associated number, and you can see the full list of available signals (with their names and numbers) by running the command kill -l
.

In order to terminate a process, a signal must be sent to it.
There are several signals that can end processes, but in this article we will focus on the most common ones: SIGTERM and SIGKILL.
SIGTERM: The Graceful Exit
When you want to kill a process that is causing problems, consuming a lot of resources, or for any other reason, most of the time you use the kill
command, as in the example below.
kill 1234
When killing a process by issuing the kill
command with the format kill [process id]
, a SIGTERM signal is sent to the process to terminate it.
After you issue the command above, this is what happens behind the scenes.
- The operating system sends the SIGTERM signal to notify process 1234 that whatever it is doing should be terminated as soon as possible.
- Before the process ends, it may run some final actions defined by the program itself. These actions can include closing open files, shutting down database connections, performing backups, or running a cleanup routine.
- After these actions are completed, the process assumes it is safe to terminate.
As you noticed, when a process receives the SIGTERM signal, it is the process’s responsibility to handle its own termination on its own terms.
You’ve probably been in situations where you try to kill a process using the kill
command, but the program keeps running.
This happens because sometimes the program is in a state where it’s not convenient to be terminated immediately, for example, in the middle of critical I/O operations or due to a bug that prevents it from shutting down when receiving the SIGTERM signal.
To make things clearer, SIGTERM is like a bouncer in a club who wants to kick you out, but tells you that you can finish your drink first before leaving 😅
Well, that’s all for the SIGTERM signal.
SIGKILL: The Forced Termination
In order to send a SIGKILL signal, you should issue the kill
command with an additional parameter, as shown in the example below.
kill -9 1234
As you can see, the kill
command receives the parameter -9
before the process ID.
If you look at the previous image that shows the list of signals, you will notice that the SIGKILL signal is associated with the number 9.
That’s what the -9
parameter represents.
SIGKILL also ends a process, but unlike SIGTERM it doesn’t notify the process or give it any chance to finish its pending tasks, because the operating system immediately removes it from memory.
As a curiosity:
when you force the termination of a process in a Linux / Mac GUI environment (through a menu or a task/process list window), behind the scenes you are sending a SIGKILL signal to the process you want to terminate.
Going back to the bouncer analogy, SIGKILL is like a bouncer who kicks you out of the club by force, without giving you a chance to finish your drink or grab your jacket from the coat check.

At this point, i can safely assume that you already know the difference between SIGTERM and SIGKILL, so let’s go straight to the code where I’ll show you a Python script that outputs a message if it receives a SIGTERM signal from the operating system.
The python script
The Python script below demonstrates how to implement a reaction to the SIGTERM signal in Python. Once executed, it will run in the foreground indefinitely.
If it receives a SIGTERM, the script will display the message "Received SIGTERM. Cleaning up before exit..." and exit gracefully.
This is possible thanks to Python’s signal
module, which allows handling the signals sent by the operating system.
On the other hand, if it receives a SIGKILL, no message will be shown because this signal cannot be caught or handled by the program.
#!/usr/bin/env python3
import signal
import sys
import time
def handle_sigterm(signum, frame):
print("SIGTERM was received. The program is doing the backups before terminating.")
sys.exit(0)
# Register handler for SIGTERM
signal.signal(signal.SIGTERM, handle_sigterm)
print("Process started. Waiting for SIGTERM... (try `kill -15 <pid>` in another terminal)")
# Keep the process alive
while True:
time.sleep(1)
Installation and Execution Permissions
Before executing the script above, make sure you are in a macOS or Linux environment and that you have Python 3 installed.
I won’t explain how to install Python 3 on macOS/Linux here, since that is out of the scope of this article. but a quick Google search will help you.
Assuming you already have Python 3 installed, you should follow these steps:
- Copy and paste the Python code above into a file named "signals-handling"
- To make things easier, move the file to your home directory (or another one of your choice).
- Assuming that the file is in the home directory, add the execution permissions by running the command: chmod +x ~/signals-handling and then type ~/signals-handling to run the script.
- Once the script is running, open another terminal on the same host and find the process ID (PID) using the
ps
command.
In my case, the PID is53275
.

- In the same terminal, assuming the PID is
53275
, send a SIGTERM signal to the process by running the command: kill 53275 - Go back to the terminal where the Python script was running and you will see that it displayed the message "SIGTERM was received. The program is doing the backups before terminating." before exiting.

If you repeat the steps above, but this time send a SIGKILL signal by running the command: KILL -9 53275 ( use your PID ), you will notice that the program simply terminates without leaving any kind of message:

Conclusion
Understanding the difference between SIGTERM and SIGKILL is a practical skill that helps sysadmins, developers, and DevOps engineers choose the safest and most effective way to terminate a process.
It’s also a best practice in real world scenarios, such as managing containers or terminating pods in Kubernetes, where graceful shutdowns can make a big difference.
I kept this explanation simple and straight to the point, avoiding unnecessary details so the distinction between both signals becomes clear once and for all.
Thanks for reading, pals.
See you next time! 😉
Comments ()