10.1. Process Management#
10.1.1. Common Pitfalls#
1. Using grep on ps output without excluding grep itself
# Problem: grep process shows up in results
ps aux | grep firefox
# Output includes: grep --color=auto firefox
# Solution: Exclude grep with [f] trick
ps aux | grep [f]irefox
# Or use pgrep
pgrep firefox
2. Assuming SIGKILL will always work
# SIGKILL doesn't work on:
# - kernel threads (kthreadd, kworker, etc.)
# - Processes in uninterruptible sleep (D state)
# Check if a process can be killed
kill -0 "$pid" 2>/dev/null && echo "Process exists"
3. Not waiting for child processes in scripts
# Bad: background process becomes zombie if parent exits
command &
# Better: wait for the background process
command &
pid=$!
wait $pid
4. Using kill on processes you don’t own
# Will fail with "Operation not permitted"
kill 12345 # If you don't own PID 12345
# Use sudo if needed (with caution)
sudo kill 12345
10.1.2. Real-World Example: Process Monitor Function#
#!/bin/bash
# Monitor a process and perform actions based on state
monitor_process() {
local pid=$1
local timeout=${2:-30}
local elapsed=0
while [[ $elapsed -lt $timeout ]]; do
if ! kill -0 "$pid" 2>/dev/null; then
echo "Process $pid has terminated"
return 0
fi
# Show current stats
if [[ -f /proc/$pid/stat ]]; then
local memory=$(awk '{print $24}' /proc/$pid/stat)
echo "[$(date '+%H:%M:%S')] PID $pid memory: $((memory / 1024))KB"
fi
sleep 1
((elapsed++))
done
echo "Timeout: Process $pid still running after $timeout seconds"
return 1
}
# Usage
long_command &
monitor_process $! 60
10.1.3. Signaling Processes#
Signals are used to communicate with processes:
Signal |
Number |
Meaning |
|---|---|---|
SIGHUP |
1 |
Hangup (reload config) |
SIGINT |
2 |
Interrupt (Ctrl+C) |
SIGKILL |
9 |
Force terminate (cannot be caught) |
SIGSTOP |
19 |
Stop (pause) |
SIGTERM |
15 |
Graceful terminate (default) |
SIGUSR1 |
10 |
User-defined 1 |
SIGUSR2 |
12 |
User-defined 2 |
10.1.3.1. Sending Signals#
# Graceful termination (allows cleanup)
kill -TERM 1234
kill 1234 # Same as above
# Force kill (immediate termination)
kill -KILL 1234
kill -9 1234
# Suspend process
kill -STOP 1234
# Resume suspended process
kill -CONT 1234
# Reload configuration
kill -HUP 1234
10.1.4. Process Information in /proc#
The /proc filesystem provides detailed process information:
10.1.4.1. Exploring /proc#
# Process 1234's information
cat /proc/1234/status # Full status
cat /proc/1234/cmdline # Command line (null-separated)
cat /proc/1234/cwd # Working directory symlink
cat /proc/1234/exe # Executable path symlink
cat /proc/1234/fd/ # Open file descriptors
cat /proc/1234/maps # Memory map
cat /proc/1234/io # I/O statistics
cat /proc/1234/limits # Resource limits
10.1.4.2. Practical Example: Get Process Info#
#!/bin/bash
get_process_info() {
local pid=$1
if [[ ! -d /proc/$pid ]]; then
echo "Process $pid not found"
return 1
fi
local name=$(cat /proc/$pid/status | grep "^Name:" | awk '{print $2}')
local state=$(cat /proc/$pid/status | grep "^State:" | awk '{print $2}')
local rss=$(cat /proc/$pid/status | grep "^VmRSS:" | awk '{print $2}')
echo "PID: $pid, Name: $name, State: $state, RSS: ${rss}KB"
}
get_process_info 1234
10.1.5. Process States#
Each process has a state indicating what it’s doing:
State |
Symbol |
Meaning |
|---|---|---|
Running |
R |
Currently executing on CPU |
Sleeping |
S |
Waiting for something (interruptible) |
Idle |
I |
Kernel thread, not runnable |
Stopped |
T |
Paused by signal (SIGSTOP) |
Zombie |
Z |
Terminated but parent hasn’t reaped it |
10.1.5.1. Understanding Zombie Processes#
# Create a zombie (parent doesn't wait for child)
bash -c 'sleep 0.1 &' &
sleep 10 # Don't wait for child
# Check for zombie with ps
ps aux | grep Z
A zombie uses minimal resources but clogs the process table. Parent should wait() for children.
10.1.6. Viewing Processes with ps#
The ps command lists processes:
10.1.6.1. Basic ps Usage#
# List all processes for current user
ps
# List all processes on system
ps aux
# List in process tree format
ps -ef
ps auxf # Tree with full format
# Custom format
ps -o pid,user,vsz,rss,comm
10.1.6.2. ps Output Fields#
# Common fields in ps aux:
# USER: process owner
# PID: process ID
# %CPU: CPU usage percentage
# %MEM: memory usage percentage
# VSZ: virtual memory size (KB)
# RSS: resident set size (KB)
# STAT: process state
# START: when process started
# TIME: CPU time used
# COMMAND: command that started the process
10.1.6.3. Filtering ps Output#
# Find processes by name
ps aux | grep firefox
# Find all processes for a user
ps -u username
# Find all processes in a process group
ps -g groupname
10.1.7. What is a Process?#
A process is a running instance of a program. Each process has:
Attribute |
Description |
|---|---|
PID |
Process ID (unique identifier) |
PPID |
Parent Process ID |
User |
Owner of the process |
Status |
Running, stopped, sleeping, zombie |
Priority |
CPU scheduling priority (nice value) |
Memory |
RAM used by the process |
CPU Time |
Total processor time used |
10.1.7.1. Process Hierarchy#
Processes form a tree structure with init (PID 1) at the root:
init (PID 1)
├── systemd (PID 4)
├── sshd (PID 1024)
│ └── bash (PID 1025)
│ └── grep (PID 1026)
└── nginx (PID 512)
├── worker (PID 513)
└── worker (PID 514)
Every process has a parent. When a parent exits, its children become orphaned and are adopted by init.