Introduction to kill
The kill command is a fundamental utility in Unix/Linux systems used to terminate or signal processes. Despite its name, kill doesn't just kill processes – it sends various signals to processes, allowing you to control their behavior. Understanding kill is essential for process management, system administration, and troubleshooting.
Basic Syntax
kill [options] <PID>... kill -l
What kill Does
- Sends signals to processes
- Terminates processes gracefully or forcefully
- Controls process behavior (pause, continue, reload, etc.)
- Lists available signals
1. Understanding Signals
What are Signals?
Signals are software interrupts sent to processes to notify them of events or request actions. Each signal has a specific meaning and default behavior.
Common Signals
| Signal | Number | Description | Default Action |
|---|---|---|---|
SIGHUP | 1 | Hangup detected | Terminate |
SIGINT | 2 | Interrupt (Ctrl+C) | Terminate |
SIGQUIT | 3 | Quit (Ctrl+) | Terminate with core dump |
SIGKILL | 9 | Kill (cannot be caught/ignored) | Terminate immediately |
SIGTERM | 15 | Termination (default kill) | Terminate |
SIGCONT | 18 | Continue if stopped | Continue execution |
SIGSTOP | 19 | Stop (cannot be caught/ignored) | Stop process |
SIGTSTP | 20 | Terminal stop (Ctrl+Z) | Stop process |
Listing Available Signals
# List all signals with numbers kill -l # List signals with names only kill -l | tr ' ' '\n' | grep -v '^$' # List specific signal kill -l 9 # Output: KILL # Get signal number from name kill -l KILL # Output: 9
2. Basic Usage
Finding Process IDs
# Find PID by process name pgrep firefox pidof firefox # Find PID with ps ps aux | grep firefox # Find all PIDs of a process pgrep -f "python script.py"
Sending Termination Signals
# Send SIGTERM (default, graceful termination) kill 1234 # Send specific signal by name kill -SIGTERM 1234 kill -TERM 1234 kill -15 1234 # Send SIGKILL (forceful, immediate termination) kill -9 1234 kill -SIGKILL 1234 kill -KILL 1234 # Kill multiple processes kill 1234 5678 9012 # Kill all processes with same name pkill firefox killall firefox
Examples
$ ps aux | grep firefox user 1234 5.2 2.1 2345678 123456 ? Sl 10:30 0:45 /usr/lib/firefox/firefox $ kill 1234 # Send SIGTERM $ kill -9 1234 # Force kill if SIGTERM doesn't work $ pgrep -f "python server.py" 5678 9012 $ kill -TERM 5678 9012 # Kill multiple
3. Signal Types and Their Uses
SIGTERM (15) - Graceful Termination
# Preferred way to terminate processes kill -15 1234 kill -TERM 1234 kill 1234 # Default is SIGTERM # Allows process to: # - Clean up resources # - Save state # - Close files properly # - Notify child processes
SIGKILL (9) - Forceful Termination
# Last resort when SIGTERM doesn't work kill -9 1234 kill -KILL 1234 # Process cannot ignore or handle this signal # No cleanup is performed # Use only when necessary
SIGHUP (1) - Hangup / Reload
# Reload configuration files (many daemons support this) kill -1 1234 kill -HUP 1234 # Examples: kill -HUP $(pgrep nginx) # Reload nginx configuration kill -HUP $(pgrep sshd) # Reload SSH daemon
SIGINT (2) - Interrupt
# Simulate Ctrl+C kill -2 1234 kill -INT 1234 # Useful for interrupting foreground processes
SIGSTOP (19) and SIGCONT (18)
# Pause a process kill -STOP 1234 kill -19 1234 # Check if process is stopped ps aux | grep 1234 # Process will show status 'T' (stopped) # Resume a stopped process kill -CONT 1234 kill -18 1234
4. Advanced Usage
Killing Process Trees
# Kill process and all its children kill -TERM -1234 # Negative PID kills process group # Using pkill with process groups pkill -TERM -g 1234 # Find and kill process tree pstree -p 1234 | grep -oP '\d+' | xargs kill -9 # Kill entire process group kill -- -$(ps -o pgid= -p 1234 | grep -o '[0-9]*')
Using pkill and pgrep
# pkill - kill processes by name pkill firefox pkill -f "python script.py" # Match full command line pkill -u username # Kill all processes of user pkill -t pts/0 # Kill all processes in terminal # pgrep - find processes by name pgrep firefox pgrep -u username -l # List with names pgrep -f "python.*server" # Regex matching # Combined example pkill -TERM -u $(whoami) python
Using killall
# Kill all processes with given name killall firefox killall -9 chrome killall -u username # Kill all processes of user # Case-insensitive matching killall -I FIREFOX # Wait for processes to die killall -w firefox # Wait until all firefox processes are gone # Interactive confirmation killall -i firefox # Ask before killing each process
5. Practical Examples
Script Examples
Process Monitor and Killer:
#!/bin/bash
# proc_killer.sh - Monitor and kill processes by resource usage
KILL_THRESHOLD_CPU=90
KILL_THRESHOLD_MEM=95
CHECK_INTERVAL=10
EXEMPT_PIDS="1 2 3" # Never kill these PIDs
check_and_kill() {
local pid=$1
local cpu=$2
local mem=$3
local name=$4
for exempt in $EXEMPT_PIDS; do
if [[ $pid -eq $exempt ]]; then
return
fi
done
if (( $(echo "$cpu > $KILL_THRESHOLD_CPU" | bc -l) )); then
echo "Killing process $pid ($name) - CPU usage: $cpu%"
kill -TERM "$pid"
sleep 2
if kill -0 "$pid" 2>/dev/null; then
echo "Process still running, using SIGKILL"
kill -9 "$pid"
fi
elif (( $(echo "$mem > $KILL_THRESHOLD_MEM" | bc -l) )); then
echo "Killing process $pid ($name) - Memory usage: $mem%"
kill -TERM "$pid"
fi
}
while true; do
ps aux | tail -n +2 | while read -r line; do
pid=$(echo "$line" | awk '{print $2}')
cpu=$(echo "$line" | awk '{print $3}')
mem=$(echo "$line" | awk '{print $4}')
name=$(echo "$line" | awk '{for(i=11;i<=NF;i++) printf "%s ", $i}')
check_and_kill "$pid" "$cpu" "$mem" "$name"
done
sleep $CHECK_INTERVAL
done
Graceful Shutdown Script:
#!/bin/bash
# graceful_shutdown.sh - Shut down processes gracefully
SHUTDOWN_TIMEOUT=30
PROCESSES=("nginx" "postgresql" "redis-server")
shutdown_process() {
local proc=$1
local pids=$(pgrep -f "$proc")
if [[ -z "$pids" ]]; then
echo "No $proc processes running"
return
fi
echo "Shutting down $proc (PIDs: $pids)"
# Send SIGTERM to all processes
for pid in $pids; do
kill -TERM "$pid"
done
# Wait for processes to terminate
local waited=0
while [[ $waited -lt $SHUTDOWN_TIMEOUT ]]; do
local remaining=""
for pid in $pids; do
if kill -0 "$pid" 2>/dev/null; then
remaining="$remaining $pid"
fi
done
if [[ -z "$remaining" ]]; then
echo "$proc shutdown successfully"
return 0
fi
sleep 1
((waited++))
done
# Force kill remaining processes
echo "$proc still running after $SHUTDOWN_TIMEOUT seconds, forcing kill"
for pid in $remaining; do
kill -9 "$pid" 2>/dev/null
done
}
# Shut down all processes
for proc in "${PROCESSES[@]}"; do
shutdown_process "$proc"
done
echo "All processes shut down"
Process Tree Killer:
#!/bin/bash
# kill_tree.sh - Kill a process and all its children
kill_tree() {
local parent_pid=$1
local signal=${2:-TERM}
# Get all child PIDs
local children=$(pgrep -P "$parent_pid")
# Recursively kill children first
for child in $children; do
kill_tree "$child" "$signal"
done
# Kill the parent
if kill -0 "$parent_pid" 2>/dev/null; then
echo "Killing $parent_pid with signal $signal"
kill -"$signal" "$parent_pid"
fi
}
# Function to kill process tree with timeout
kill_tree_timeout() {
local parent_pid=$1
local timeout=${2:-10}
# Try graceful termination first
kill_tree "$parent_pid" TERM
# Wait for processes to die
local waited=0
while [[ $waited -lt $timeout ]]; do
if ! kill -0 "$parent_pid" 2>/dev/null; then
echo "Process tree terminated successfully"
return 0
fi
sleep 1
((waited++))
done
# Force kill if still running
echo "Timeout reached, forcing kill"
kill_tree "$parent_pid" KILL
}
# Main script
if [[ $# -lt 1 ]]; then
echo "Usage: $0 <parent_pid> [timeout]"
exit 1
fi
kill_tree_timeout "$1" "${2:-10}"
6. Signal Handling in Scripts
Trapping Signals
#!/bin/bash
# trap_example.sh - Demonstrating signal trapping
cleanup() {
echo "Cleaning up temporary files..."
rm -f /tmp/temp_*
echo "Exiting gracefully"
exit 0
}
handle_interrupt() {
echo "Received interrupt signal (Ctrl+C)"
cleanup
}
handle_terminate() {
echo "Received termination signal"
cleanup
}
handle_hangup() {
echo "Received hangup signal, reloading configuration"
# Reload configuration logic here
}
# Set traps for various signals
trap handle_interrupt SIGINT SIGTERM
trap handle_hangup SIGHUP
trap cleanup EXIT
echo "Process $$ running. PID: $$"
echo "Press Ctrl+C to test interrupt"
echo "Send signals: kill -HUP $$ for reload"
# Simulate work
while true; do
echo "Working..."
sleep 2
done
Checking if Process Exists
# Check if process is running
if kill -0 1234 2>/dev/null; then
echo "Process 1234 is running"
else
echo "Process 1234 is not running"
fi
# Wait for process to end
while kill -0 1234 2>/dev/null; do
echo "Waiting for process 1234 to terminate..."
sleep 1
done
# Function to check process
is_running() {
kill -0 "$1" 2>/dev/null
return $?
}
7. Process Groups and Sessions
Understanding Process Groups
# Show process groups ps -eo pid,pgid,cmd | head -10 # Kill entire process group kill -TERM -1234 # Negative PID = process group # Find process group of a process ps -o pgid= -p 1234 # Kill all processes in same group as PID kill -TERM -- -$(ps -o pgid= -p 1234 | tr -d ' ')
Job Control
# Start a background job long_running_command & # List jobs jobs # Bring job to foreground fg %1 # Send job to background bg %1 # Kill job by job number kill %1 kill -9 %2
8. Security Considerations
Permissions
# Can only kill your own processes (unless root) kill 1 # Cannot kill init process as normal user # Output: bash: kill: (1) - Operation not permitted # Check process ownership ps -o user= -p 1234 # Root can kill any process sudo kill -9 1234
Safe Killing Practices
# Always try SIGTERM first kill -TERM 1234 # Wait a bit sleep 5 # Check if still running if kill -0 1234 2>/dev/null; then echo "Process still running, using SIGKILL" kill -9 1234 fi # Never kill critical system processes # Process 1 (init/systemd) - don't kill! # Kernel processes (usually in [brackets]) - don't kill!
9. Monitoring and Logging
Logging Killed Processes
#!/bin/bash
# kill_logger.sh - Log all kill commands
LOG_FILE="/var/log/kill_monitor.log"
# Function to log kills
log_kill() {
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
local user=$(whoami)
local pid=$1
local signal=$2
local process_info=$(ps -p "$pid" -o comm= 2>/dev/null)
echo "$timestamp - User: $user - PID: $pid - Signal: $signal - Process: $process_info" >> "$LOG_FILE"
}
# Override kill command
kill() {
local pid=$1
local signal=${2:-TERM}
# Log the kill attempt
log_kill "$pid" "$signal"
# Execute real kill
command kill "$@"
}
# Example usage
kill 1234
kill -9 5678
Audit Trail
# Check audit logs for kill commands sudo ausearch -m task -c kill # Check process history lastcomm | grep kill # Monitor kill commands with auditd sudo auditctl -a exit,always -S kill
10. Troubleshooting
Common Issues
# Process won't die kill -9 1234 # Still running? # Check if process is zombie ps aux | grep 1234 # Zombie shows as 'Z' in STAT column # Permission denied kill 1234 # Error: Operation not permitted # Check ownership and try with sudo # No such process kill 1234 # Error: No such process # Process already terminated # Signal number out of range kill -100 1234 # Error: Invalid signal # Check valid signals with kill -l
Debugging
# Trace system calls for kill strace -e kill kill 1234 # Check signal handling of process cat /proc/1234/status | grep -i sig # See pending signals ps -o pending= -p 1234 # Monitor signals to process kill -CONT 1234
11. Integration with Other Commands
Using with ps
# Kill processes by pattern
ps aux | grep python | awk '{print $2}' | xargs kill -9
# Kill processes older than certain time
ps -eo pid,etime,cmd | grep "python" | awk '$2 ~ /[0-9]+-[0-9]+:[0-9]+/ {print $1}' | xargs kill
# Kill processes with specific state
ps -eo pid,stat,cmd | grep "^ *[0-9]\+ Z" | awk '{print $1}' | xargs kill -9 # Kill zombies
Using with find
# Kill processes using specific files
lsof /path/to/file | tail -n +2 | awk '{print $2}' | xargs kill -9
# Kill processes in specific directory
find /proc -maxdepth 1 -type d -name "[0-9]*" 2>/dev/null | \
while read proc; do
if readlink "$proc/cwd" | grep -q "/target/dir"; then
kill -9 $(basename "$proc")
fi
done
Using with systemctl (systemd)
# For system services, use systemctl instead of kill sudo systemctl stop nginx sudo systemctl kill nginx # Sends SIGKILL to all processes of service sudo systemctl kill -s HUP nginx # Send specific signal
12. Signal Table Reference
Complete Signal List
| # | Name | Description | Default Action |
|---|---|---|---|
| 1 | SIGHUP | Hangup detected | Terminate |
| 2 | SIGINT | Interrupt from keyboard | Terminate |
| 3 | SIGQUIT | Quit from keyboard | Core dump |
| 4 | SIGILL | Illegal instruction | Core dump |
| 5 | SIGTRAP | Trace/breakpoint trap | Core dump |
| 6 | SIGABRT | Abort signal | Core dump |
| 7 | SIGBUS | Bus error | Core dump |
| 8 | SIGFPE | Floating point exception | Core dump |
| 9 | SIGKILL | Kill signal | Terminate |
| 10 | SIGUSR1 | User-defined signal 1 | Terminate |
| 11 | SIGSEGV | Invalid memory reference | Core dump |
| 12 | SIGUSR2 | User-defined signal 2 | Terminate |
| 13 | SIGPIPE | Broken pipe | Terminate |
| 14 | SIGALRM | Timer signal | Terminate |
| 15 | SIGTERM | Termination signal | Terminate |
| 16 | SIGSTKFLT | Stack fault | Terminate |
| 17 | SIGCHLD | Child stopped or terminated | Ignore |
| 18 | SIGCONT | Continue if stopped | Continue |
| 19 | SIGSTOP | Stop process | Stop |
| 20 | SIGTSTP | Stop typed at terminal | Stop |
| 21 | SIGTTIN | Terminal input for background | Stop |
| 22 | SIGTTOU | Terminal output for background | Stop |
| 23 | SIGURG | Urgent condition on socket | Ignore |
| 24 | SIGXCPU | CPU time limit exceeded | Core dump |
| 25 | SIGXFSZ | File size limit exceeded | Core dump |
| 26 | SIGVTALRM | Virtual alarm clock | Terminate |
| 27 | SIGPROF | Profiling timer expired | Terminate |
| 28 | SIGWINCH | Window resize signal | Ignore |
| 29 | SIGIO | I/O now possible | Terminate |
| 30 | SIGPWR | Power failure | Terminate |
| 31 | SIGSYS | Bad system call | Core dump |
13. Best Practices
Kill Command Best Practices
- Always try SIGTERM first:
kill -TERM 1234 sleep 5 kill -0 1234 2>/dev/null && kill -9 1234
- Check process ownership:
if [[ $(ps -o user= -p 1234) == "$USER" ]]; then kill 1234 else sudo kill 1234 fi
- Verify process exists:
if kill -0 1234 2>/dev/null; then kill -TERM 1234 else echo "Process 1234 not running" fi
- Use process groups for related processes:
kill -TERM -1234 # Kill entire process group
- Log important kills:
logger "Killing process 1234 (high CPU usage)" kill -9 1234
Safety Checklist
- [ ] Is this my process or do I have permission?
- [ ] Is this a critical system process?
- [ ] Have I tried SIGTERM before SIGKILL?
- [ ] Are there dependent services that might be affected?
- [ ] Have I saved all important data?
- [ ] Do I have the correct PID?
- [ ] Is there a more graceful shutdown method available?
14. Quick Reference Card
Common Kill Commands
| Command | Description |
|---|---|
kill 1234 | Send SIGTERM to PID 1234 |
kill -9 1234 | Send SIGKILL to PID 1234 |
kill -TERM 1234 | Send SIGTERM by name |
kill -SIGKILL 1234 | Send SIGKILL by full name |
kill -l | List all signals |
kill -l 9 | Get name of signal 9 |
killall firefox | Kill all firefox processes |
pkill -f "python script" | Kill processes matching pattern |
pgrep firefox | Find firefox PIDs |
kill -STOP 1234 | Suspend process |
kill -CONT 1234 | Resume process |
kill -HUP 1234 | Hangup/reload process |
Signal Quick Reference
| Signal | Number | Use Case |
|---|---|---|
| SIGTERM | 15 | Graceful termination (default) |
| SIGKILL | 9 | Forceful termination (last resort) |
| SIGHUP | 1 | Reload configuration |
| SIGINT | 2 | Interrupt (Ctrl+C) |
| SIGSTOP | 19 | Suspend process |
| SIGCONT | 18 | Resume suspended process |
| SIGUSR1 | 10 | User-defined action |
| SIGUSR2 | 12 | User-defined action |
Exit Codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Failure (unspecified) |
| 2 | Invalid option |
| 64 | Invalid signal specification |
| 65 | Process not found |
Conclusion
The kill command is essential for process management in Unix/Linux systems:
Key Points Summary
- Signals:
killsends signals, not just termination requests - Default Signal: SIGTERM (15) - graceful termination
- Force Kill: SIGKILL (9) - immediate termination (last resort)
- Process Groups: Use negative PIDs to kill process groups
- Permissions: Can only kill your own processes (except root)
- Signal Handling: Processes can trap and handle many signals
- Multiple Tools:
kill,pkill,killallfor different use cases
Best Practices
- Always try SIGTERM first - Allow processes to clean up
- Use SIGKILL only when necessary - It doesn't allow cleanup
- Verify PIDs - Ensure you're killing the right process
- Check permissions - Use sudo when needed
- Consider dependencies - Killing one process may affect others
- Log important kills - For audit and troubleshooting
- Use process groups - For related processes
Quick Reference
| Situation | Command |
|---|---|
| Normal termination | kill 1234 |
| Force termination | kill -9 1234 |
| Reload config | kill -HUP 1234 |
| Suspend process | kill -STOP 1234 |
| Resume process | kill -CONT 1234 |
| Kill by name | pkill firefox |
| Kill all with name | killall firefox |
| List signals | kill -l |
| Check if running | kill -0 1234 |
The kill command's versatility in sending different signals makes it an indispensable tool for process control, from graceful shutdowns to forceful terminations and everything in between.
Complete Bash Exercises with Solutions
Practice Bash scripting with solved exercises to improve your command-line and scripting skills.
Link: https://macronepal.com/complete-bash-exercises-with-solutions/
Complete Guide to Bash Crontab Command
Learn how to schedule and automate tasks efficiently using the Bash crontab command.
Link: https://macronepal.com/complete-guide-to-bash-crontab-command-schedule-tasks/
Complete Guide to Bash Arrays
Understand how to create, manage, and use arrays in Bash scripting.
Link: https://macronepal.com/complete-guide-to-bash-arrays/
Bash Quiz: Test Your Knowledge
Test your Bash scripting knowledge with quizzes and practical questions.
Link: https://macronepal.com/bash-quiz-test-your-knowledge/
Complete Guide to Bash Functions
Learn how to write reusable Bash functions for cleaner and efficient scripts.
Link: https://macronepal.com/complete-guide-to-bash-functions/
Complete Guide to Bash Loops
Master loops in Bash for repetitive tasks and automation.
Link: https://macronepal.com/complete-guide-to-bash-loops/
Complete Guide to Bash If-Else Statements
Learn decision-making in Bash using conditional statements.
Link: https://macronepal.com/complete-guide-to-bash-ifelse-statements/
Complete Guide to Bash Operators
Explore arithmetic, logical, and comparison operators in Bash.
Link: https://macronepal.com/complete-guide-to-bash-operators/
Complete Guide to Bash Data Types
Understand variables and different data types used in Bash scripting.
Link: https://macronepal.com/complete-guide-to-bash-data-types/
Complete Guide to Bash Variables
Learn how to declare, assign, and use variables in Bash scripts.
Link: https://macronepal.com/complete-guide-to-bash-variables/
Complete Guide to Bash Scripting
A complete introduction to writing Bash scripts for automation.
Link: https://macronepal.com/complete-guide-to-bash-scripting/
Complete Guide to Basic Bash Syntax
Learn the fundamental syntax needed to write Bash commands and scripts.
Link: https://macronepal.com/complete-guide-to-basic-bash-syntax/
Complete Guide to Bash Chgrp Command
Learn how to change group ownership of files and directories.
Link: https://macronepal.com/complete-guide-to-bash-chgrp-command-change-group-ownership-2/
Complete Guide to Bash Chgrp Command (Alternate)
Another detailed explanation of Bash group ownership management.
Link: https://macronepal.com/complete-guide-to-bash-chgrp-command-change-group-ownership/
Complete Guide to Bash File Permissions and Ownership
Understand Linux file permissions and ownership management.
Link: https://macronepal.com/complete-guide-to-bash-file-permissions-and-ownership/
Complete Guide to Bash Chmod Command
Learn how to modify file permissions using chmod.
Link: https://macronepal.com/complete-guide-to-bash-chmod-command-change-file-permissions/
Complete Guide to Bash Chown Command
Change file ownership using the Bash chown command.
Link: https://macronepal.com/complete-guide-to-bash-chown-command-change-file-ownership/
Complete Guide to Bash SCP Command
Securely transfer files between systems using SCP.
Link: https://macronepal.com/complete-guide-to-bash-scp-command-secure-copy/
Complete Guide to Bash SSH Command
Learn secure remote access and server management using SSH.
Link: https://macronepal.com/complete-guide-to-bash-ssh-command/
Bash Wget Command Complete Guide
Download files from the internet using the wget command.
Link: https://macronepal.com/bash-wget-command-complete-guide-to-non-interactive-network-downloader/
