# 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. ```bash # 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: ```bash # 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`. ```bash # 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`: ```bash # 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). ```bash # 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 request - `TERM` (15) — Termination signal, default `kill` signal - `HUP` (1) — Hangup signal, sent when terminal closes - `EXIT` (pseudo-signal) — Fires when script exits normally or via error - `KILL` (9) — Cannot be trapped; force-kills the process ```bash # 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: ```bash # 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 ```