Advanced Bash Scripting
Take your Bash scripting skills to the next level with these advanced techniques and patterns.
Process Management
# Run command in background
command &
# Get PID of last background command
bg_pid=$!
# Wait for background process to complete
wait $bg_pid
# Kill process by PID
kill $bg_pid
# Kill all child processes on exit
trap 'kill $(jobs -p)' EXIT
Parallel Execution
# Run commands in parallel
command1 &
command2 &
command3 &
wait # Wait for all to complete
# Limit parallel processes
max_jobs=4
for item in "${items[@]}"; do
while (( $(jobs | wc -l) >= max_jobs )); do
sleep 0.1
done
process_item "$item" &
done
wait
Named Pipes (FIFOs)
# Create a named pipe
mkfifo mypipe
# Writer process
echo "data" > mypipe &
# Reader process
while read line; do
echo "Received: $line"
done < mypipe
# Clean up
rm mypipe
Signal Handling
# Handle signals
trap 'cleanup' EXIT
trap 'echo "Interrupted!"; exit 1' INT TERM
# Ignore signals
trap '' HUP # Ignore hangup signal
# Temporary ignore
trap '' INT
# ... critical section ...
trap - INT # Restore default behavior
Advanced Parameter Expansion
# Default values
${var:-default} # Use default if var is unset or empty
${var:=default} # Assign default if var is unset or empty
${var:?error} # Display error if var is unset or empty
# String manipulation
${var#pattern} # Remove shortest prefix match
${var##pattern} # Remove longest prefix match
${var%pattern} # Remove shortest suffix match
${var%%pattern} # Remove longest suffix match
${var/old/new} # Replace first match
${var//old/new} # Replace all matches
${var:offset} # Substring from offset
${var:offset:length} # Substring with length
# Array operations
${array[@]:start:length} # Array slice
${!array[@]} # All array indices
${#array[@]} # Number of elements
Co-Processes
# Start co-process
coproc myproc {
while read -r input; do
echo "Processing: $input"
done
}
# Send to co-process
echo "data" >&${myproc[1]}
# Read from co-process
read -r output <&${myproc[0]}
echo "Received: $output"
Advanced I/O Redirection
# Redirect both stdout and stderr to file
command >file 2>&1
command &>file
# Redirect stderr to stdout and stdout to file
command 2>&1 >file
# Tee to multiple files
command | tee file1 file2 >/dev/null
# Redirect to multiple commands
command | tee >(grep error > errors.log) >(grep warning > warnings.log) > output.log
Script Templates
A robust script template with common features:
#!/bin/bash
# Strict mode
set -euo pipefail
# Configuration
SCRIPT_NAME=$(basename "$0")
VERSION="1.0.0"
LOG_FILE="${SCRIPT_NAME%.*}.log"
# Help function
usage() {
cat <&2
elif [[ -z ${QUIET:-} ]]; then
echo -e "$timestamp [$level] $message"
fi
echo "$timestamp [$level] $message" >> "$LOG_FILE"
}
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help) usage; exit 0 ;;
-v|--version) echo "$SCRIPT_NAME $VERSION"; exit 0 ;;
-d|--debug) DEBUG=1; set -x ;;
-q|--quiet) QUIET=1 ;;
*) break ;;
esac
shift
done
# Main function
main() {
log "INFO" "Starting $SCRIPT_NAME"
# Check requirements
if ! command -v required_command &>/dev/null; then
log "ERROR" "required_command not found"
exit 1
fi
# Process arguments
if [[ $# -eq 0 ]]; then
log "ERROR" "No arguments provided"
usage
exit 1
fi
# Main logic here
for arg in "$@"; do
log "INFO" "Processing: $arg"
done
log "INFO" "Script completed successfully"
}
# Run main function
main "$@"
Performance Optimization
- Use builtins instead of external commands when possible
- Avoid unnecessary subshells
- Use shell parameter expansion instead of external tools like sed/awk for simple operations
- Minimize file I/O operations
- Use arrays instead of repeated string processing
Security Considerations
- Always quote variables to prevent word splitting and globbing
- Validate and sanitize all input
- Use
--
to signify end of options in commands that accept filenames - Set restrictive permissions on sensitive scripts
- Consider using
set -o noclobber
to prevent accidental file overwrites
Further Learning
To continue mastering Bash scripting:
- Read the Bash Reference Manual
- Study the Bash FAQ
- Practice with real-world scripting challenges
- Explore the source code of well-written Bash utilities