kill & killall Commands

Process Termination and Signal Management in Linux

Overview

kill sends signals to processes by PID (Process ID), while killall sends signals to all processes matching a name. These commands are fundamental tools for process management, allowing administrators to gracefully terminate, forcefully stop, or send custom signals to running processes.

kill vs killall: Key Differences

kill: Targets specific processes by PID number. More precise, requires knowing the exact PID. Cannot accidentally affect multiple processes unless you specify multiple PIDs.

killall: Targets all processes matching a process name. More convenient but potentially dangerous if multiple processes share the same name. Sends signals to ALL matching processes simultaneously.

⚠️ Critical Warning: killall in Solaris and older UNIX systems terminates ALL processes and can crash the system. On Linux, killall only affects processes matching the specified name. Always verify your operating system before using killall.

Common Signals Reference

Signal Number Description Can Be Caught?
SIGTERM 15 Graceful termination (default) Yes
SIGKILL 9 Immediate termination (cannot be caught) No
SIGHUP 1 Hangup (often used to reload config) Yes
SIGINT 2 Interrupt (Ctrl+C) Yes
SIGQUIT 3 Quit with core dump Yes
SIGUSR1 10 User-defined signal 1 Yes
SIGUSR2 12 User-defined signal 2 Yes
SIGSTOP 19 Pause process (cannot be caught) No
SIGCONT 18 Continue paused process Yes

kill Command Examples

Example 1: Basic Process Termination (Graceful)

$ kill 12345

Sends the default SIGTERM (signal 15) to process ID 12345. This is the preferred method for stopping a process as it allows the process to:

  • Close open files properly
  • Release locks and resources
  • Perform cleanup operations
  • Save state or write final data

Most well-written applications catch SIGTERM and shut down gracefully. Always try SIGTERM before SIGKILL.

Best Practice: Wait 10-30 seconds after sending SIGTERM before escalating to SIGKILL. Check if the process has terminated with "ps -p 12345" or "kill -0 12345".

Example 2: Force Kill (SIGKILL)

$ kill -9 12345
$ kill -KILL 12345
$ kill -SIGKILL 12345

Immediately terminates process 12345 without allowing cleanup. SIGKILL cannot be caught, blocked, or ignored by the process. The kernel forcefully terminates the process.

When to use SIGKILL:

  • Process doesn't respond to SIGTERM after reasonable wait time
  • Process is completely frozen/hung
  • Emergency situations requiring immediate termination
⚠️ Warning: SIGKILL can cause data corruption, incomplete writes, orphaned child processes, unreleased locks, and lost work. Use only as a last resort after SIGTERM fails.

Example 3: Reload Configuration (SIGHUP)

$ kill -HUP 5432
$ kill -1 5432

Sends SIGHUP to process 5432, typically used to reload configuration files without restarting the service. Commonly used with:

  • Apache/nginx: Reload configuration and log files
  • syslogd: Reopen log files (useful after log rotation)
  • sshd: Reload sshd_config
  • Many daemons: Re-read configuration without losing connections
Note: Not all processes handle SIGHUP the same way. Check the application's documentation. Some processes terminate on SIGHUP (the traditional behavior from terminal hangup), while daemons typically use it for configuration reload.

Example 4: Kill Multiple Processes by PID

$ kill 1234 5678 9012
$ kill -15 $(pgrep firefox)
$ kill $(ps aux | grep 'python script.py' | grep -v grep | awk '{print $2}')

Multiple methods to terminate several processes:

First command: Explicitly lists multiple PIDs to send SIGTERM.

Second command: Uses command substitution with pgrep to find all Firefox PIDs and terminate them.

Third command: Complex pipeline that finds PIDs of specific Python script, excludes the grep process itself, extracts PIDs with awk, and passes them to kill.

Example 5: Check if Process Exists (Signal 0)

$ kill -0 12345 && echo "Process exists" || echo "Process not found"
$ if kill -0 12345 2>/dev/null; then
> echo "Process 12345 is running"
> else
> echo "Process 12345 is not running"
> fi

Signal 0 is a special signal that doesn't actually send a signal to the process. Instead, it performs error checking to see if the process exists and if you have permission to signal it.

Use cases:

  • Verify process is still running before attempting operations
  • Check if you have permission to signal a process
  • Monitor scripts to detect when a process terminates
  • Healthcheck scripts and monitoring systems
Tip: Redirect stderr (2>/dev/null) to suppress error messages when the process doesn't exist. The exit code will still indicate success (0) or failure (non-zero).

Example 6: Stop and Continue Process (Job Control)

$ kill -STOP 12345 # Pause the process
$ kill -19 12345 # Same as STOP
$ ps -p 12345 -o state # Check state (T = stopped)
$ kill -CONT 12345 # Resume the process
$ kill -18 12345 # Same as CONT

SIGSTOP pauses (suspends) a process without terminating it. The process remains in memory but stops executing. SIGCONT resumes execution.

Practical applications:

  • Temporarily pause CPU-intensive tasks during high-load periods
  • Debugging: Pause process to examine state with debugging tools
  • Testing how applications handle suspend/resume cycles
  • Resource management: Temporarily suspend background processes
Note: SIGSTOP cannot be caught or ignored (like SIGKILL). The process will be paused unconditionally. Use SIGTSTP (Ctrl+Z signal) if you need a catchable stop signal.

Example 7: Kill Process and All Children

$ kill -TERM -12345 # Negative PID kills process group
$ pkill -P 12345 # Kill all children of PID 12345
$ kill -- -12345 # Alternative syntax with double dash

A negative PID tells kill to signal an entire process group instead of a single process. Process group ID is typically the PID of the parent process that created the group.

Understanding process groups:

  • Processes in a pipeline share a process group
  • Shells create process groups for job control
  • Parent processes often create process groups for their children
  • Useful for ensuring related processes terminate together
Alternative: Use "pkill -P 12345" to specifically target child processes of PID 12345, or use "pstree -p 12345" to visualize the process tree before killing.

Example 8: Send User-Defined Signals

$ kill -USR1 8765 # Application-specific signal
$ kill -USR2 8765 # Another custom signal
$ kill -10 8765 # SIGUSR1 by number
$ kill -12 8765 # SIGUSR2 by number

SIGUSR1 and SIGUSR2 are user-defined signals that applications can handle for custom purposes. These have no predefined meaning in the kernel.

Common uses:

  • nginx: SIGUSR1 reopens log files (log rotation)
  • Apache: SIGUSR1 performs graceful restart
  • dd: SIGUSR1 prints current progress
  • Custom applications: Trigger internal state changes, toggle debug mode, dump statistics

Example 9: List All Available Signals

$ kill -l # List all signal names
$ kill -l TERM # Get signal number for TERM
$ kill -l 15 # Get signal name for number 15
$ trap -l # Alternative: shell built-in trap command

The -l option lists all available signals on your system. Signal numbers can vary slightly between UNIX systems, though common signals (TERM=15, KILL=9) are standardized.

Output includes signals like: HUP INT QUIT ILL TRAP ABRT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM STKFLT CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH POLL PWR SYS

Example 10: Advanced Kill with Error Handling

#!/bin/bash
# Graceful process termination with timeout
PID=$1
TIMEOUT=30

if ! kill -0 $PID 2>/dev/null; then
echo "Process $PID does not exist or no permission"
exit 1
fi

echo "Sending SIGTERM to process $PID"
kill -TERM $PID

# Wait for process to terminate
for i in $(seq 1 $TIMEOUT); do
if ! kill -0 $PID 2>/dev/null; then
echo "Process terminated gracefully after $i seconds"
exit 0
fi
sleep 1
done

echo "Process did not terminate, sending SIGKILL"
kill -9 $PID
sleep 1

if kill -0 $PID 2>/dev/null; then
echo "ERROR: Failed to kill process $PID"
exit 1
else
echo "Process terminated forcefully"
exit 0
fi

Production-ready script demonstrating proper process termination:

  1. Verifies process exists and you have permissions
  2. Attempts graceful termination with SIGTERM
  3. Waits up to 30 seconds for process to exit
  4. Escalates to SIGKILL if process doesn't respond
  5. Provides detailed logging and proper exit codes
Production Use: This pattern should be used in init scripts, systemd service units, and any automation that manages processes. Respects graceful shutdown while ensuring processes don't hang indefinitely.

killall Command Examples

Example 1: Basic Usage - Kill All by Process Name

$ killall firefox
$ killall chrome
$ killall -v apache2 # Verbose output

Terminates ALL processes with the exact name "firefox" or "chrome". The -v option provides verbose output showing which processes were signaled.

Important considerations:

  • Process name must match exactly (case-sensitive)
  • Maximum process name length is typically 15 characters
  • Only kills processes you own (unless run as root)
  • Sends SIGTERM by default (graceful termination)
⚠️ Caution: killall terminates ALL matching processes simultaneously. If you have multiple Firefox windows or Chrome instances, all will be terminated. Verify with "ps aux | grep processname" before using killall.

Example 2: Force Kill All Instances

$ killall -9 firefox
$ killall -KILL chrome
$ killall --signal KILL python

Forcefully terminates all instances of the named process using SIGKILL. Useful when processes are frozen or not responding to normal termination signals.

⚠️ Warning: Forceful termination of all instances can lead to data loss across multiple windows/sessions. Try "killall -TERM processname" first and wait before escalating to SIGKILL.

Example 3: Interactive Mode - Confirm Before Killing

$ killall -i firefox
$ killall --interactive chrome

Prompts for confirmation before signaling each process. This is a safety feature that shows the PID and asks "Kill process firefox(12345) ? (y/n)" for each matching process.

Best for:

  • Uncertain about which processes will be affected
  • Multiple instances running, want to kill only specific ones
  • Learning environment or when teaching others
  • Production systems where mistakes are costly

Example 4: Match Processes by User

$ killall -u username firefox
$ killall --user craig httpd
$ sudo killall -u www-data php-fpm # As root, kill another user's processes

Kills processes matching both the process name AND the specified username. Useful in multi-user systems or when processes run under service accounts.

Use cases:

  • Kill all of a user's processes when terminating their session
  • Target web server processes running under www-data account
  • Clean up processes after user logout
  • Service account management and maintenance

Example 5: Dry Run - Show What Would Be Killed

$ killall -w firefox # Wait for processes to die
$ killall --exact httpd # Match exact name only
$ pgrep firefox # Alternative: show PIDs without killing

The -w option waits for all processes to die, then returns. The --exact option ensures only exact matches are killed, not partial matches.

Testing before killing: Use "pgrep firefox" to see which processes would be affected, or "ps aux | grep firefox" to see full details before running killall.

Example 6: Older Than Time Specification

$ killall -o 8h firefox # Kill processes older than 8 hours
$ killall --older-than 24h chrome # Kill processes running over 24 hours
$ killall -o 1d httpd # Kill processes older than 1 day

Targets only processes that have been running longer than the specified time. Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks), M (months), y (years).

Practical applications:

  • Clean up zombie or stuck processes that ran too long
  • Maintenance scripts that kill long-running sessions
  • Resource management: Terminate processes exceeding time limits
  • Testing: Kill only old instances while keeping new ones

Example 7: Younger Than Time Specification

$ killall -y 5m firefox # Kill processes younger than 5 minutes
$ killall --younger-than 1h chrome # Kill recent processes only

Opposite of -o option - targets only recently started processes. Useful for cleanup after accidental mass-launch or testing scenarios.

Example scenario: You accidentally launched 50 Chrome instances. "killall -y 2m chrome" would kill only those launched in the last 2 minutes, preserving your main Chrome session that's been running for hours.

Example 8: Case-Insensitive Matching

$ killall -I firefox # Match Firefox, FIREFOX, FiRefoX, etc.
$ killall --ignore-case Chrome

The -I option makes process name matching case-insensitive. Helpful when process names may have varying capitalization or you're unsure of the exact case.

Note: Linux process names are typically lowercase, but this option is useful for cross-platform scripts or when dealing with user-created process names.

Example 9: Regular Expression Matching

$ killall -r 'python.*' # Match python, python3, python3.9, etc.
$ killall --regexp 'http.*' # Match httpd, http-server, etc.
$ killall -r '^java$' # Match exactly "java"

The -r option enables regular expression matching for process names. This is more flexible than exact string matching.

Regex examples:

  • '^python' - Processes starting with "python"
  • 'daemon$' - Processes ending with "daemon"
  • 'test.*process' - Contains "test" followed by "process"
  • '(apache|nginx)' - Either apache or nginx
⚠️ Warning: Regex matching can be dangerous. Test with "pgrep -f 'your-regex'" first to see what would be matched before using killall with -r.

Example 10: Quiet Mode and Return Codes

$ killall -q firefox && echo "Killed successfully" || echo "No processes found"
$ killall --quiet chrome
$ if killall -q -r 'test.*'; then
> echo "Test processes terminated"
> else
> echo "No test processes running"
> fi

The -q option suppresses output and sets return codes: 0 if at least one process was killed, 1 if no processes matched.

Scripting applications:

  • Silent cleanup in automation scripts
  • Conditional logic based on whether processes existed
  • Cron jobs that should run quietly
  • Error handling in deployment scripts
#!/bin/bash
# Example script with proper error handling
if killall -q old-daemon; then
echo "Old daemon terminated, starting new version..."
/usr/local/bin/new-daemon &
else
echo "No old daemon running, starting fresh..."
/usr/local/bin/new-daemon &
fi

Advanced Tips and Best Practices

  • Always verify before killing: Use "ps aux | grep processname" or "pgrep -a processname" to see what will be affected
  • Prefer kill over killall: When you know the exact PID, use kill for precision
  • Use pkill as alternative: pkill offers more flexible pattern matching than killall
  • Understand signal handlers: Check documentation to see how applications respond to different signals
  • Monitor after killing: Verify processes terminated with "pgrep processname" or check process count changes
  • Log your actions: In production, log what processes were killed and why
  • Test in non-production first: Especially with killall, test in dev environment before production
  • Use timeout for SIGTERM: Give processes time to clean up before escalating to SIGKILL
  • Consider alternatives: systemctl, service commands, or application-specific stop commands may be better
  • Document expected behavior: In scripts, comment what signals you're using and why

Related Commands

  • pkill: More flexible pattern matching, similar to killall but uses pgrep-style matching
  • pgrep: Find processes by name without killing them
  • ps: Display process information
  • top/htop: Interactive process monitoring
  • pstree: Display process tree hierarchy
  • killall5: System V initialization tool (use during system shutdown)
  • timeout: Run command with time limit and kill if exceeded
  • systemctl: Manage systemd services (preferred for system daemons)