Advanced¶
Deep dive into advanced bash concepts: job control, subshells, signals, and performance optimization.
Topics¶
Job Control¶
Managing background processes, nohup, disown, and running jobs after terminal close.
Subshells¶
Understanding subshells, command substitution, process substitution, and their implications for variable scope.
Signals¶
Unix signals, the trap command, handling interrupts, and graceful shutdown patterns.
Performance¶
Optimizing bash scripts: avoiding common performance pitfalls, when to use external tools, and profiling techniques.
Prerequisites¶
This section assumes familiarity with:
- Basic scripting (variables, conditionals, loops)
- Functions and scope
- Process concepts (PIDs, exit codes)
- Basic I/O redirection
Why These Topics Matter¶
Job Control¶
Essential for:
- Running long processes without tying up the terminal
- Managing multiple concurrent tasks
- Keeping processes alive after SSH disconnect
- Development workflows with background servers
Subshells¶
Understanding subshells prevents bugs related to:
- Variables not persisting after pipes
- Unexpected process isolation
- Performance from unnecessary forks
- Proper use of
$()and()
Signals¶
Critical for:
- Graceful shutdown handling
- Cleanup on script interruption
- Inter-process communication
- Robust production scripts
Performance¶
Important for:
- Scripts that process large files
- Avoiding unnecessary external commands
- Understanding when bash is (not) the right tool
- Production script optimization
Key Concepts Preview¶
Job Control¶
# Run in background
./server.sh &
# Keep running after logout
nohup ./server.sh &
disown
# Wait for background jobs
wait
Subshells¶
# Subshell - variables don't persist
(cd /tmp && pwd) # Back to original after
# Command substitution runs in subshell
output=$(some_command)
# Pipe creates subshell
echo "data" | while read line; do
var="$line" # Won't persist!
done
Signals¶
# Cleanup on exit
trap 'rm -f $tmpfile' EXIT
# Handle Ctrl+C
trap 'echo "Interrupted"; exit 1' INT
# Ignore signal
trap '' TERM
Performance¶
# Slow - external command in loop
for i in {1..1000}; do
result=$(echo "$i * 2" | bc)
done
# Fast - bash arithmetic
for i in {1..1000}; do
((result = i * 2))
done
Common Patterns¶
These topics combine into powerful patterns:
Daemon Script¶
#!/usr/bin/env bash
cleanup() {
echo "Shutting down..."
kill $worker_pid 2>/dev/null
rm -f "$pidfile"
}
trap cleanup EXIT INT TERM
pidfile="/var/run/mydaemon.pid"
echo $$ > "$pidfile"
while true; do
do_work &
worker_pid=$!
wait $worker_pid
sleep 60
done
Parallel Processing¶
#!/usr/bin/env bash
max_jobs=4
for file in *.txt; do
while (( $(jobs -r -p | wc -l) >= max_jobs )); do
sleep 0.1
done
process "$file" &
done
wait
Graceful Timeout¶
#!/usr/bin/env bash
timeout=30
( sleep $timeout; kill $$ 2>/dev/null ) &
timer_pid=$!
trap "kill $timer_pid 2>/dev/null" EXIT
# Long running work here
do_work
# Completed before timeout
kill $timer_pid 2>/dev/null
When to Use What¶
| Situation | Approach |
|---|---|
| Long-running task | Background job + disown |
| Need output later | nohup with output file |
| Cleanup required | trap EXIT |
| Handle Ctrl+C | trap INT |
| Parallel processing | Background jobs + wait |
| Variable in pipe | Process substitution or here-string |
| Isolated environment | Subshell () |