BASH
Implement Robust Error Handling and Logging in Bash
Create more reliable bash scripts by incorporating comprehensive error handling with `set -e`, `trap`, and functions for structured logging to stdout and a log file.
#!/bin/bash
# --- Configuration ---
LOG_FILE="/tmp/myscript.log"
DATE_FORMAT="+%Y-%m-%d %H:%M:%S"
# --- Logging Functions ---
log() {
echo "$(date "$DATE_FORMAT") [INFO] $1" | tee -a "$LOG_FILE"
}
warn() {
echo "$(date "$DATE_FORMAT") [WARN] $1" | tee -a "$LOG_FILE" >&2
}
error() {
echo "$(date "$DATE_FORMAT") [ERROR] $1" | tee -a "$LOG_FILE" >&2
}
# --- Error Handling ---
_cleanup() {
log "Script finished or terminated. Cleaning up..."
# Add any cleanup commands here (e.g., remove temp files)
# rm -f /tmp/mytempfile.txt
}
_error_exit() {
local last_command="$BASH_COMMAND"
local exit_code=$?
error "Last command '${last_command}' failed with exit code ${exit_code} on line ${BASH_LINENO[0]}."
_cleanup
exit "${exit_code}"
}
# Exit immediately if a command exits with a non-zero status.
set -e
# Execute _error_exit function on EXIT signal (normal exit or error)
# trap '_error_exit' EXIT # This will call _error_exit on any exit, success or failure.
# A more common approach:
trap '_error_exit' ERR
# Execute _cleanup function on SIGHUP, SIGINT, SIGQUIT, SIGTERM
trap '_cleanup' SIGHUP SIGINT SIGQUIT SIGTERM
# --- Main Script Logic ---
log "Script started."
# Example commands (some might fail)
echo "Performing task 1..."
sleep 1
log "Task 1 complete."
echo "Attempting a command that might fail (e.g., trying to remove a non-existent dir with -r)..."
rm -r non_existent_directory_123 || warn "Could not remove non_existent_directory_123 as expected (it didn't exist)."
echo "Attempting a command that WILL fail and trigger error trap..."
# This command is expected to fail and exit due to 'set -e'
# The 'trap ERR' will then catch it.
cp /non/existent/source /tmp/destination_file
log "This line will not be reached if the above 'cp' command fails."
# If the script reaches here, it means no critical error occurred.
log "Script completed successfully."
_cleanup # Manual call if trap EXIT is not used and script ends successfully
How it works: This script provides robust error handling and structured logging. `set -e` ensures the script exits immediately if any command fails. The `trap ERR` command registers `_error_exit` to run whenever a command returns a non-zero exit status, providing details about the failure. A separate `_cleanup` function is called on various termination signals (SIGHUP, SIGINT, etc.) via `trap` to ensure resources are released. Custom `log`, `warn`, and `error` functions write messages to both standard output and a designated log file.