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.