A signal interrupts a process to notify it of an event, with no payload beyond the signal number itself. A process can choose to handle most signals with custom logic, ignore them, or take the kernel's default action - but a couple of signals can't be caught or ignored at all.

Signals you'll actually use

Signal Number Default action Typical use
SIGHUP 1 Terminate Historically "terminal hung up"; commonly repurposed by daemons to mean "reload your config"
SIGINT 2 Terminate What Ctrl+C sends - "interrupt"
SIGQUIT 3 Terminate + core dump Ctrl+, similar to SIGINT but requests a core dump
SIGKILL 9 Terminate Immediate, unconditional termination - cannot be caught, blocked, or ignored
SIGTERM 15 Terminate The polite way to ask a process to exit - the default signal kill sends
SIGSTOP 19 Stop Pause the process - cannot be caught or ignored, like SIGKILL's "pause" counterpart
SIGCONT 18 Continue Resume a stopped process
SIGUSR1 / SIGUSR2 10 / 12 Terminate No fixed meaning - reserved for applications to define their own use

List every signal name and number a system supports with kill -l.

SIGTERM vs. SIGKILL

This is the distinction that matters most in practice. SIGTERM asks a process to shut down and lets it clean up first - close file handles, flush buffers, finish an in-flight request, remove a lock file. SIGKILL gives the process no choice or opportunity to react at all; the kernel just removes it. Because a killed process can't run its own cleanup code, SIGKILL should be a last resort for something that's genuinely hung, not a routine way to stop a service - a database killed with SIGKILL mid-write is a much more likely source of corruption than one given a chance to shut down cleanly with SIGTERM.

This is also why systemctl stop sends SIGTERM first, waits a configurable timeout, and only escalates to SIGKILL if the process hasn't exited by then - see systemd and Services.

Sending signals

kill 1234              # SIGTERM to PID 1234 (the default signal)
kill -9 1234            # SIGKILL, by number
kill -SIGKILL 1234      # SIGKILL, by name
kill -HUP 1234           # ask a daemon to reload config, if it supports it
killall nginx            # signal every process matching a name
pkill -f "python worker" # signal by matching the full command line

Handling signals in scripts

Bash scripts can intercept signals with trap, useful for cleanup before exiting:

#!/usr/bin/env bash
cleanup() {
  echo "cleaning up temp files"
  rm -f /tmp/mylock
}
trap cleanup EXIT SIGINT SIGTERM

touch /tmp/mylock
sleep 60

Here, cleanup runs whether the script finishes normally, is interrupted with Ctrl+C, or receives SIGTERM - but not if it's killed with SIGKILL, since that signal never reaches the process to be trapped. See Shell Scripting for more on trap and script-level error handling.

Job control and signals

Suspending a foreground job with Ctrl+Z sends it SIGTSTP, a catchable variant of SIGSTOP; resuming it with fg or bg sends SIGCONT. See Job Control for the full set of foreground/ background job commands these signals sit behind.