Linux Signals

Signals are the simplest form of inter-process communication in Linux — a way for the kernel or another process to say "hey, something happened" to a process. The kill command is misleadingly named; it actually sends any signal, not just the killing kind.

What is a Signal?

A signal is an asynchronous notification sent to a process. When a signal arrives, the process's normal execution is interrupted and a signal handler runs. Signals are identified by number or name.

# List all signals kill -l # Send signal by number kill -9 1234 # SIGKILL kill -15 1234 # SIGTERM (default when you just run: kill 1234) # Send signal by name kill -SIGTERM 1234 kill -HUP 1234 # reload config

The Most Important Signals

SignalNumberDefault ActionCommon Use
SIGTERM15Terminate gracefullyNormal shutdown — process can catch and clean up
SIGKILL9Terminate immediatelyForce kill — cannot be caught, blocked, or ignored
SIGHUP1Terminate (or reload)Tell daemon to reload config (nginx, sshd)
SIGINT2TerminateCtrl+C in terminal
SIGQUIT3Terminate + core dumpCtrl+\\ — like SIGINT but dumps memory
SIGSTOP19Pause processUncatchable pause
SIGCONT18Resume processResume after SIGSTOP or SIGTSTP
SIGTSTP20Pause processCtrl+Z — catchable
SIGCHLD17IgnoredChild process state changed
SIGSEGV11Terminate + core dumpSegmentation fault — invalid memory access
SIGUSR1/210/12TerminateApplication-defined (e.g., toggle debug logging)

Catching Signals in Shell Scripts

#!/bin/bash # Catch SIGTERM and clean up before exiting cleanup() { echo "Cleaning up..." rm -f /tmp/myapp.lock exit 0 } trap cleanup SIGTERM SIGINT echo "Running... PID=$$" while true; do sleep 1 done

Why SIGKILL Cannot Be Caught

Why is SIGKILL special? SIGKILL is handled entirely by the kernel — it never reaches the process's signal handler. The kernel forcibly terminates the process and reclaims its resources. This is why a process stuck in D state (uninterruptible sleep) can't be killed even with SIGKILL — the kernel handles signals only when returning from kernel space, which a D-state process isn't doing.

Best practice: always try SIGTERM first and wait a few seconds. Only escalate to SIGKILL if the process doesn't respond.

# Graceful shutdown pattern kill -TERM 1234 sleep 5 kill -0 1234 2>/dev/null && kill -KILL 1234 # force if still alive