Linux Signals Reference

Linux signals reference — SIGTERM (15), SIGKILL (9), SIGHUP (1), SIGINT (2). kill -SIGNAL pid, trap signals in bash. What each signal does and when to use it.

5 min read

What it is

A reference for understanding and managing Linux signals, which are a fundamental mechanism for inter-process communication and controlling process behavior.

Installation

Signals are a built-in part of the Linux kernel. No installation is required.

Core Concepts

  • Signal: An asynchronous notification sent to a process to indicate an event has occurred.
  • Process ID (PID): A unique number assigned to each running process. Signals are typically sent to a specific PID.
  • Signal Handler: A function within a process that is executed when a specific signal is received.
  • Default Action: The action a process takes if it doesn’t have a specific handler for a signal (e.g., terminate, ignore, dump core).
  • Signal Mask: A set of signals that are currently blocked from being delivered to a process.

Commands / Usage

Sending Signals (kill)

The kill command sends a signal to a process.

  • Send SIGTERM (terminate gracefully):

    kill -15 12345
    

    Requests the process with PID 12345 to shut down cleanly.

  • Send SIGKILL (force terminate):

    kill -9 12345
    

    Immediately terminates the process with PID 12345 without allowing it to clean up.

  • Send SIGHUP (hang up, often reload configuration):

    kill -1 12345
    

    Notifies the process with PID 12345 that its controlling terminal has been closed, often used to signal daemons to reload their configuration.

  • List available signals:

    kill -l
    

    Displays a numbered list of all signals supported by the system.

Sending Signals (killall)

The killall command sends a signal to processes by name.

  • Terminate all processes named 'nginx' gracefully:

    killall -15 nginx
    

    Sends SIGTERM to all processes whose executable name is nginx.

  • Force terminate all processes named 'apache2':

    killall -9 apache2
    

    Sends SIGKILL to all processes whose executable name is apache2.

  • Send SIGHUP to all processes named 'sshd':

    killall -1 sshd
    

    Sends SIGHUP to all processes whose executable name is sshd.

Sending Signals (pkill)

The pkill command sends signals to processes based on patterns in their names or other attributes.

  • Terminate processes whose command line contains 'my_app':

    pkill -15 my_app
    

    Sends SIGTERM to processes whose command line matches the pattern my_app.

  • Force terminate processes owned by user 'johndoe' named 'worker':

    pkill -9 -u johndoe worker
    

    Sends SIGKILL to processes named worker that are owned by the user johndoe.

  • Send SIGHUP to processes whose full path contains '/opt/myapp/bin':

    pkill -1 -f /opt/myapp/bin
    

    Sends SIGHUP to processes whose full command line (including path) matches /opt/myapp/bin.

Viewing Process Signals (ps)

The ps command can display signal information.

  • Show state of all processes, including signal status:
    ps aux
    
    The STAT column shows the process state, including letters indicating signal status (e.g., S for sleeping, R for running, T for stopped, Z for zombie, + for foreground process group).

Managing Process Signals (trap in shell scripts)

The trap command in shell scripts allows you to specify actions to take when certain signals are received.

  • Clean up a temporary file when SIGINT or SIGTERM is received:

    #!/bin/bash
    trap 'rm -f /tmp/my_temp_file; exit 0' SIGINT SIGTERM
    echo "Process $$ running. Press Ctrl+C to exit."
    while true; do
        sleep 1
    done
    

    This script will remove /tmp/my_temp_file and exit gracefully if interrupted by Ctrl+C (SIGINT) or a kill command (SIGTERM).

  • Ignore SIGQUIT:

    trap '' SIGQUIT
    

    Configures the shell to ignore the SIGQUIT signal.

  • Execute a command on EXIT:

    trap 'echo "Exiting..."' EXIT
    

    Runs echo "Exiting..." whenever the script exits, regardless of the reason.

Viewing Process Status (top, htop)

Interactive process viewers can show signal-related information.

  • Check signal status in top: Run top. Look for the S column which indicates the process state (e.g., R, S, D, T, Z).

  • Check signal status in htop: Run htop. The State column provides similar information to top.

Common Patterns

  • Gracefully restarting a service:

    sudo systemctl restart nginx
    # or if not using systemd
    sudo kill -1 12345 # Assuming 12345 is the PID of the nginx master process
    

    Sending SIGHUP to a daemon process often triggers a configuration reload or restart.

  • Finding and killing a runaway process:

    pgrep -f "my_problematic_script.py"
    # Note the PID returned, e.g., 56789
    kill -9 56789
    

    Use pgrep to find the PID of a process based on its name or command line, then use kill -9 to force termination if it’s unresponsive.

  • Killing all processes associated with a user:

    kill -9 $(ps -u username -o pid=)
    

    This command first lists all PIDs for username using ps, then pipes them to kill -9.

  • Terminating a process and its children (using pkill):

    pkill -P parent_pid
    

    Sends a signal to all processes whose parent PID is parent_pid.

Gotchas

  • kill -9 is a blunt instrument: While effective for stopping unresponsive processes, SIGKILL cannot be caught or ignored. The process has no chance to save its state, clean up resources, or exit gracefully, which can lead to data corruption. Use SIGTERM (-15) first.
  • killall vs. pkill: killall matches the exact process name. pkill uses regular expressions and can match against the full command line (-f) or other process attributes. Be careful with killall if you have multiple processes with similar names.
  • Zombie Processes (Z state): A zombie process is one that has terminated but whose parent process has not yet read its exit status. They consume minimal resources but indicate a potential issue with the parent process. They cannot be killed directly.
  • Signal Handling in C/C++: When writing C/C++ programs, signals can be handled using signal() or sigaction(). sigaction() is generally preferred for its finer control and portability.
  • Signals are not queues: If multiple signals of the same type are sent to a process, it may only be delivered once. Signals are typically not queued.
  • Permissions: You can only send signals to processes that you own, or if you are root.
  • Default Actions Vary: The default action for each signal is important. For example, SIGINT usually terminates, while SIGUSR1 is often ignored by default.