wiki:shell-processes
Table of Contents
Shell Processes
Background and Foreground
Run commands in the background by appending & to allow the shell prompt to return immediately. Use fg and bg to move jobs between foreground and background.
# Run in background (shell returns immediately) long_running_task & # List all jobs jobs # Bring last job to foreground fg # Bring specific job to foreground (e.g., job 1) fg %1 # Resume a suspended job in background bg # Run command and get its PID curl http://example.com & echo $! # Print the background job PID
Manage multiple background jobs:
# Start multiple background jobs sleep 100 & # Job 1 sleep 200 & # Job 2 sleep 300 & # Job 3 # List all jobs with status jobs -l # Show job numbers and PIDs # Bring job 2 to foreground fg %2 # Kill job 1 kill %1 # Wait for all background jobs wait # Wait for specific job wait $!
Job Control
Use Ctrl+Z to suspend (pause) a foreground job without terminating it. The job can be resumed later with fg or bg.
# Suspend current foreground job (Ctrl+Z) # [1]+ Stopped vim myfile.txt # Resume in background bg # List suspended job jobs # [1]+ Stopped vim myfile.txt # Resume in foreground fg %vim # Bring vim back to foreground
Prevent shell exit from terminating background jobs using disown or nohup:
# Start a long task backup.sh & # Disown the job (it persists after shell exits) disown %1 # Alternative: use nohup to ignore hangup signals nohup long_task.sh & # Output redirected to nohup.out by default nohup long_task.sh > task.log 2>&1 &
Traps and Signals
Use trap to run code when the shell receives a signal. Common signals include SIGINT (Ctrl+C), SIGTERM (termination request), SIGHUP (hangup), and SIGKILL (cannot be trapped).
# Trap Ctrl+C and exit cleanly trap 'echo "Interrupt caught"; exit' INT # Trap multiple signals trap 'cleanup' INT TERM EXIT cleanup() { echo "Cleaning up..." rm -f "$tmpfile" kill "$bg_job" 2>/dev/null } # Temporary file that gets deleted on exit tmpfile=$(mktemp) trap "rm -f '$tmpfile'" EXIT # ... use tmpfile ...
Common signals and their uses:
INT(2) — Interrupt signal (Ctrl+C), graceful termination requestTERM(15) — Termination signal, defaultkillsignalHUP(1) — Hangup signal, sent when terminal closesEXIT(pseudo-signal) — Fires when script exits normally or via errorKILL(9) — Cannot be trapped; force-kills the process
# Log script activity log_file="/tmp/script.log" trap 'echo "Script interrupted at $(date)" >> "$log_file"' INT # Save state before exit state_file="/tmp/app_state" trap 'save_state' EXIT save_state() { echo "Current state: $counter" > "$state_file" } # Cleanup on error trap 'echo "Error on line $LINENO"; exit 1' ERR # Wait for background job and trap termination long_task & pid=$! trap 'kill $pid 2>/dev/null' TERM EXIT wait $pid
Use kill -l to list all available signals:
# List all signals kill -l # Send specific signal to process kill -SIGTERM $pid # Request termination kill -SIGKILL $pid # Force kill (cannot be trapped) kill -SIGSTOP $pid # Suspend (like Ctrl+Z) kill -SIGCONT $pid # Resume suspended process
wiki/shell-processes.md · Last modified: by 127.0.0.1
