The kill command in Linux
kill sends a signal to a process — despite the name, not always a lethal one. The default signal, SIGTERM (15), politely asks the program to shut down, letting it save state and clean up. SIGKILL (9) is the last resort: the kernel terminates the process instantly, no questions asked, no cleanup. Always try plain kill before kill -9.
How kill works
Signals are the kernel's asynchronous tap on a process's shoulder, and kill is the syscall (and command) that sends them. Each signal has a default action — terminate for SIGTERM, ignore for SIGCHLD, stop for SIGSTOP — and a process may install handlers to override defaults: catch SIGTERM to flush buffers and exit cleanly, catch SIGHUP to reload configuration. A signal is a number and a convention; the graceful behavior lives in the receiving program.
Two signals cannot be caught, blocked or ignored: SIGKILL and SIGSTOP. That is a deliberate guarantee — the administrator always holds a lever the process cannot wire shut. It also defines SIGKILL's cost: the process gets no final instruction, so nothing is flushed, no temp files removed, no locks released. Permission-wise, you may signal only your own processes (matching UID); root signals anything. The rare SIGKILL survivor is a process in uninterruptible I/O sleep (state D) — it is not resisting; it simply cannot hear anything until the kernel-level I/O returns.
Syntax
kill [-SIGNAL] PID... Common options
| Option | What it does |
|---|---|
(default) | SIGTERM (15): request a graceful shutdown. |
-9 | SIGKILL: force termination immediately. Cannot be caught or ignored. |
-HUP | SIGHUP (1): many daemons reload their configuration on this signal. |
-STOP / -CONT | Pause a process and resume it later. |
-l | List all signal names. |
How to use kill: examples
$ kill 4321 Ask process 4321 to terminate gracefully.
$ kill -9 4321 Force it. Use only when the polite version was ignored.
$ killall node Signal every process by name instead of PID.
$ pkill -f "python server.py" Signal processes whose full command line matches a pattern.
$ kill -HUP $(pgrep nginx | head -1) Tell a daemon to reload configuration without downtime.
Real-world use cases for kill
Freeing a port a dead app still holds
"Address already in use" on port 3000: kill $(lsof -t -i:3000) terminates whatever holds it. The lsof -t flag prints bare PIDs precisely so they can be fed to kill like this.
Graceful restarts without dropped requests
Sending SIGHUP instead of killing: kill -HUP $(cat /var/run/nginx.pid) makes nginx re-read config and gracefully cycle workers — the mechanism behind every zero-downtime reload.
Pro tips and common mistakes
- Escalate politely: kill PID, wait a few seconds, and only then kill -9. Well-written software uses the grace period to save state.
- kill -0 PID sends no signal but returns success if the process exists — the idiomatic "is it alive?" test in scripts.
- pkill matches on name (pkill -f "python worker.py"); test the match first with pgrep -f -l to see exactly what would die.
- A process that survives kill -9 is almost certainly in D state (uninterruptible I/O, often NFS) — the fix is unsticking the I/O, not more signals.
Frequently asked questions about kill
What is the difference between kill and kill -9?
Plain kill sends SIGTERM, which the program can handle: close files, flush data, exit cleanly. kill -9 sends SIGKILL, which the program never sees — the kernel just removes it. -9 risks corrupted files and orphaned locks, so it is the fallback, not the default.
How do I find the PID to kill?
ps aux | grep programname, or directly pgrep programname. pkill and killall skip the PID step entirely by matching on the name.
Why does a process survive kill -9?
Almost nothing survives SIGKILL. The exceptions are processes in uninterruptible I/O sleep (state D, usually stuck on disk/NFS) and zombies, which are already dead and only need their parent to acknowledge them.
Related commands
Find lines matching a pattern in files or piped input — the workhorse of text search.
psSee what is running, find a process ID, and combine with grep to hunt down a program.