kmail.at
← learning

sysadmin · difficulty ◆◆

kill — send signals to processes

It is not about killing — it is about sending signals. SIGTERM asks, SIGKILL doesn't.

The name is a lie. kill does not kill anything — it sends a signal, and most of the time the process gets to decide what happens next. That one misunderstanding is why people reach for kill -9 first and break their own servers.

AI-generated draft · reviewed and editedThis text was generated with AI as a first draft, then reviewed and edited by the author, who holds editorial responsibility for it.

2026-09-01 · 5 min read

$ kill

What it does

kill sends a signal to a process by PID. The default signal is SIGTERM (15), which politely asks the process to terminate — the process can catch it, clean up, and exit gracefully. kill -9 sends SIGKILL, which the kernel enforces immediately and the process cannot catch, ignore, or handle. There is a whole spectrum in between: SIGHUP (1) makes daemons reload configs, SIGINT (2) is what Ctrl-C sends, SIGSTOP (19) freezes a process, SIGCONT (18) resumes it.

Why it matters

Every stuck process, hung service, and runaway job on a Linux box is resolved with kill. But the discipline matters more than the command: you start with SIGTERM and give the process a moment to exit cleanly, and only escalate to SIGKILL when it refuses. kill -9 is a last resort, not a first instinct — a process killed with SIGKILL gets no chance to flush buffers, close files, or tell its children to stop, which is how you end up with corrupted databases and orphaned processes.

What the process does with the signal you sent

Handing a signal to a process is a request against its signal disposition, and there are only three possibilities. Most signals have a default action the kernel carries out unless the program has done something about them: signal(7)'s table lists SIGHUP, SIGINT, SIGTERM, SIGKILL and SIGUSR1 as Term — terminate — SIGSTOP as Stop and SIGCONT as Cont. A program can also install a handler and decide for itself, which is what almost every daemon does with SIGHUP: sshd 'rereads its configuration file when it receives a hangup signal, SIGHUP, by executing itself with the name and options it was started with', and nginx's own signal list gives HUP as 'changing configuration'. Finally a program can ignore a signal outright, or block it while it finishes something — and exactly two signals are beyond all of that. signal(7) states it plainly: 'The signals SIGKILL and SIGSTOP cannot be caught, blocked, or ignored.' That one sentence is the whole reason kill -9 always works and is still the last resort: nothing is asked of the process, and nothing is cleaned up.

Example

$ ps -o pid,stat,cmd -p 1009164
    PID STAT CMD
1009164 S    sleep 300

First, find the PID. ps -p <pid> confirms what you are about to signal — never kill a PID you have not identified.

$ kill 1009164
(no output — signal sent)
$ ps -o pid,stat,cmd -p 1009164
    PID STAT CMD
ps exit=1

kill with no flag sends SIGTERM. The process exits cleanly; ps now finds nothing (exit 1). No output from kill itself is normal — silence means success.

$ kill -9 1009211
/tmp/killtest.sh: line 21: 1009211 Killed                  sleep 300
    PID STAT CMD
ps exit=1

-9 sends SIGKILL. The shell prints 'Killed' because the process was terminated by the kernel without a chance to clean up. Use this only when SIGTERM failed.

$ kill -0 1009220 && echo 'PID 1009220 is alive'
PID 1009220 is alive

kill -0 sends no signal at all — it only checks whether the process exists and you have permission to signal it. Perfect for health checks in scripts.

$ kill -l | head -3
 1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP
 6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM

kill -l lists every signal and its number. SIGTERM is 15, SIGKILL is 9, SIGHUP is 1 — the three you will actually use.

$ kill -HUP 1234
(no output — nginx reloaded its config)

SIGHUP is the classic 'reload your config' signal. nginx, sshd, and many daemons re-read their config files on HUP instead of dying — a graceful way to apply changes without downtime.

Common flags

kill <pid>
send SIGTERM (15) — ask the process to terminate gracefully
kill -9 <pid>
send SIGKILL — kernel terminates it immediately, cannot be caught
kill -HUP <pid>
send SIGHUP (1) — many daemons reload their config
kill -0 <pid>
check if a process exists and is signalable, without sending a real signal
kill -l
list all signal names and numbers
kill -STOP <pid>
freeze a process (SIGSTOP); resume with kill -CONT
killall <name>
signal every process matching a name, e.g. killall nginx — a separate program (psmisc), not part of kill itself, and not present on every minimal system
kill -l <signal>
Translate between a name and a number: kill -l 9 prints KILL, kill -l TERM prints 15. Handy when a log line or a core dump names a signal by number. Note that `kill` is usually a shell builtin, and bash prints the whole numbered table while /bin/kill -l (procps-ng) prints bare names with no numbers.

History

Origin

kill has been in Unix since its earliest editions in the early 1970s — the command dates to 1973 in the Bell Labs research system. The name is a historical accident: the original use case was terminating a process, so it was called kill, but the mechanism it exposes (signals) is far more general. The signal system itself, with SIGTERM, SIGKILL, and the rest, was designed in at Bell Labs and has survived essentially unchanged for fifty years.

Why SIGKILL is special

SIGKILL (9) and SIGSTOP (19) are the only two signals a process cannot catch or ignore — the kernel handles them directly. That is why kill -9 always works but is also dangerous: the process gets zero chance to clean up. SIGTERM, by contrast, is a request the process can handle, which is why well-behaved programs trap it to flush data and shut down their children before exiting.

Fun facts

Pros & cons

pros

  • + Precise: signal one PID, or every process by name with killall
  • + Graceful by default — SIGTERM lets processes clean up before exiting
  • + The signal system is universal: every Unix-like system has kill and the same signals

cons

  • − Easy to kill the wrong process if you do not verify the PID first
  • − kill -9 can corrupt data and orphan children when used carelessly
  • − No built-in way to find PIDs — you must pair it with ps, pgrep, or top

Takeaways

  1. 1Start with SIGTERM (plain kill) and only escalate to kill -9 if the process survives
  2. 2Verify the PID with ps -p <pid> before you signal it — never kill blind
  3. 3Use kill -0 <pid> in scripts to check if a process is still running
  4. 4Send SIGHUP to nginx, sshd, and other daemons to reload configs without downtime
  5. 5killall <name> signals every process by name — handy but be sure you mean all of them

Related commands