Process management in Shell scripts includes starting, monitoring, terminating processes, and inter-process communication.
Process Starting
Background Execution
bash# Run command in background command & # Run in background and ignore hangup signal nohup command & # Use disown to detach process from current shell command & disown %1
Subprocess
bash# Create subprocess using parentheses (command1; command2) & # Variables in subprocess don't affect parent ( local_var="child" echo "Child: $local_var" ) echo "Parent: $local_var" # Output: Parent: (empty)
Process Monitoring
View Processes
bash# View all processes ps aux # View processes for specific user ps -u username # View specific process ps -p PID # Real-time process monitoring top htop # View process tree pstree
Find Processes
bash# Find process using grep ps aux | grep "nginx" # Find process ID using pgrep pgrep nginx # Find process ID using pidof pidof nginx # View detailed process information ps -p $(pgrep nginx) -o pid,ppid,cmd
Monitor Process Status
bash# Check if process is running if ps -p PID > /dev/null; then echo "Process is running" else echo "Process is not running" fi # Use pgrep to check if pgrep -x "nginx" > /dev/null; then echo "nginx is running" fi
Process Termination
Terminate Processes
bash# Send SIGTERM signal (normal termination) kill PID # Send SIGKILL signal (force termination) kill -9 PID # Terminate process by name pkill process_name # Terminate all matching processes killall process_name
Signal Types
bash# Common signals kill -l # List all signals # SIGHUP (1) - Reload configuration kill -1 PID # SIGINT (2) - Interrupt (Ctrl+C) kill -2 PID # SIGTERM (15) - Normal termination kill -15 PID # SIGKILL (9) - Force termination kill -9 PID
Wait for Processes
bash# Start background process command & PID=$! # Wait for process to complete wait $PID # Wait for all background processes wait # Check process exit status wait $PID exit_status=$? echo "Exit status: $exit_status"
Inter-Process Communication
Signal Communication
bash# Script that catches signals #!/bin/bash trap 'echo "Received SIGINT"; exit' INT trap 'echo "Received SIGTERM"; exit' TERM while true; do echo "Running..." sleep 1 done
Pipe Communication
bash# Anonymous pipe command1 | command2 # Named pipe (FIFO) mkfifo /tmp/my_pipe cat > /tmp/my_pipe & cat < /tmp/my_pipe
File Communication
bash# Use files for communication lock_file="/tmp/script.lock" # Create lock file if [ -f "$lock_file" ]; then echo "Script is already running" exit 1 fi touch "$lock_file" # Execute tasks # ... # Delete lock file rm -f "$lock_file"
Practical Application Examples
Process Daemon Script
bash#!/bin/bash # Daemon process script daemon_process() { local command="$1" local lock_file="/tmp/${command}.lock" # Check lock file if [ -f "$lock_file" ]; then local pid=$(cat "$lock_file") if ps -p "$pid" > /dev/null 2>&1; then echo "$command is already running (PID: $pid)" return 1 else rm -f "$lock_file" fi fi # Start process $command & local pid=$! echo $pid > "$lock_file" echo "Started $command (PID: $pid)" return 0 } # Use daemon process daemon_process "nginx"
Process Monitoring Script
bash#!/bin/bash # Process monitoring script monitor_process() { local process_name="$1" local max_memory="$2" # MB local max_cpu="$3" # % while true; do # Get process information local pid=$(pgrep -x "$process_name") if [ -z "$pid" ]; then echo "$process_name is not running" sleep 5 continue fi # Get memory usage local memory=$(ps -p "$pid" -o rss= | awk '{print $1/1024}') # Get CPU usage local cpu=$(ps -p "$pid" -o %cpu=) echo "$process_name (PID: $pid) - Memory: ${memory}MB, CPU: ${cpu}%" # Check if exceeds threshold if (( $(echo "$memory > $max_memory" | bc -l) )); then echo "Warning: Memory usage exceeds ${max_memory}MB" fi if (( $(echo "$cpu > $max_cpu" | bc -l) )); then echo "Warning: CPU usage exceeds ${max_cpu}%" fi sleep 5 done } # Use monitoring script monitor_process "nginx" 512 80
Batch Process Management
bash#!/bin/bash # Batch kill processes kill_processes() { local pattern="$1" local signal="${2:-15}" local pids=$(pgrep -f "$pattern") if [ -z "$pids" ]; then echo "No processes found matching: $pattern" return 1 fi echo "Killing processes: $pids" kill -$signal $pids sleep 2 # Check if processes are still running for pid in $pids; do if ps -p "$pid" > /dev/null 2>&1; then echo "Process $pid still running, forcing kill" kill -9 "$pid" fi done echo "All processes killed" } # Use batch kill kill_processes "python.*script.py"
Process Restart Script
bash#!/bin/bash # Process restart script restart_process() { local process_name="$1" local command="$2" echo "Restarting $process_name..." # Terminate process local pid=$(pgrep -x "$process_name") if [ -n "$pid" ]; then echo "Stopping $process_name (PID: $pid)" kill "$pid" sleep 2 # Check if still running if ps -p "$pid" > /dev/null 2>&1; then echo "Force killing $process_name" kill -9 "$pid" fi fi # Start process echo "Starting $process_name..." $command & local new_pid=$! sleep 2 # Check if started successfully if ps -p "$new_pid" > /dev/null 2>&1; then echo "$process_name restarted successfully (PID: $new_pid)" return 0 else echo "Failed to start $process_name" return 1 fi } # Use restart script restart_process "nginx" "nginx -g 'daemon off;'"
Process Management Best Practices
- Use nohup and disown: Ensure processes continue running after shell exits
- Use lock files: Prevent duplicate process starts
- Terminate processes gracefully: Prefer SIGTERM over SIGKILL
- Monitor process status: Regularly check if processes are running normally
- Log process information: Facilitate troubleshooting and debugging
- Use signal handling: Implement graceful process shutdown
- Set resource limits: Prevent processes from consuming too many resources
- Use process groups: Easier to manage related processes