bash trap - ghdrako/doc_snipets GitHub Wiki

trap [options] "[arguments]" [signals]

Arguments are the commands trap executes upon detecting a signal. Unless the command is only one word, it should be enclosed with quotation marks " ". If the argument contains more than one command, separate them with a semicolon ;.

Perform necessary cleanup operations in all situation

pseudo-signal provided by bash, called EXIT, that you can trap; commands or functions trapped on it will execute when the script exits for any reason.

cleanup() {
  # do the cleanup
}

trap cleanup EXIT

Example

    #!/bin/bash
    scratch=$(mktemp -d -t tmp.XXXXXXXXXX)
    function finish {
      rm -rf "$scratch"
    }
    trap finish EXIT

Display a List of Signal Names and Their Numbers

trap -l

Using Traps to Ensure Service Availability

#!/bin/bash
# Set trap on EXIT for service
trap "systemctl start smb.service" EXIT

# Stop service
systemctl stop smb.service

# Create the tarball
tar czf windows_share.tar.gz /srv/WindowsTeam/

# There is no need to restart the service in the script, 
# the trap will catch any exit, even successful

Ensure a Port is Closed After Script Completion

#!/bin/bash
trap "iptables -D INPUT -p tcp -s 10.0.0.222 --dport 32400 -j ACCEPT" EXIT
echo "Opening ports for kiddos 2 hours of TV time"
iptables -I INPUT -p tcp -s 10.0.0.222 --dport 32400 -j ACCEPT
sleep 7200

Ensure a File Cleanup

#!/bin/bash
trap "rm -f /tmp/output.txt" EXIT
yum -y update > /tmp/output.txt
if grep -qi "kernel" /tmp/output.txt; then
     mail -s "KERNEL UPDATED" [email protected] < /tmp/output.txt
fi

Example

Define a function to handle errors

handle_error() {
echo "Error occurred at line $1: $2"
exit $3
}

Set up trap to call handle_error function on error (ERR signal)

trap 'handle_error $LINENO "$BASH_COMMAND" $?' ERR

Example function that may encounter an error

divide() {
local dividend=$1
local divisor=$2
Check for division by zero
(( divisor == 0 )) && { echo "Error: Division by zero"; exit 1; }
result=$((dividend / divisor))
echo "Result of division: $result"
}

Example usage

echo "Attempting division"
divide 10 0

Trap signals like SIGINT (Ctrl+C) to perform cleanup operations before exiting.

graceful_exit() {
  Cleanup tasks if needed
  exit "$1"
}

trap 'cleanup_on_interrupt; graceful_exit 130' INT
cleanup_on_interrupt() {
  Cleanup tasks before exiting on interrupt
  echo "Interrupt signal received. Cleaning up..."
}

Logging Errors on Exit

log_error() {
  local error_message="$1"
  echo "Error: $error_message" >> error_log.txt
}
trap 'log_error "Unexpected error occurred."; graceful_exit 1' ERR