Bash trap Command - Handle Signals
Using the trap Command
The trap command runs a command when your script receives a signal, or when it exits.
It is most often used to clean up, for example to delete temporary files, even if the script is stopped early.
Syntax
trap 'commands' SIGNAL
Common signals:
EXIT: The script ends, for any reasonINT: The user pressed Ctrl+CTERM: The script was asked to stop (for example bykill)ERR: A command failed
Run Code When the Script Ends
A trap on EXIT always runs when the script ends:
Example: Trap EXIT
Save this as bye.sh:
#!/bin/bash
trap 'echo "Goodbye!"' EXIT
echo "Working..."
Run it:
./bye.sh
Working...
Goodbye!
Clean Up Temporary Files
Put the cleanup code in a function, and call it from the trap. The temporary file is removed even if the script fails or is stopped:
Example: Remove a Temporary File
Save this as cleanup.sh:
#!/bin/bash
tmpfile=$(mktemp)
cleanup() {
rm -f "$tmpfile"
echo "Removed the temporary file"
}
trap cleanup EXIT
echo "data" > "$tmpfile"
echo "Using the temporary file"
Run it:
./cleanup.sh
Using the temporary file
Removed the temporary file
Catch Ctrl+C
A trap on INT runs when the user presses Ctrl+C. Here, the script prints a message and exits:
Example: Trap INT
Save this as wait.sh:
#!/bin/bash
trap 'echo " Stopped by user"; exit 130' INT
echo "Press Ctrl+C to stop"
sleep 60
Run it:
./wait.sh
Press Ctrl+C to stop
^C Stopped by user
The Try it Yourself editor has no Ctrl+C, so its versions of the INT examples send the signal with kill -INT $$ ($$ is the script's own process ID).
Ignore a Signal
Use an empty string to ignore a signal. This script cannot be stopped with Ctrl+C while the loop runs:
#!/bin/bash
trap '' INT
for i in 1 2 3 4 5; do
echo "Step $i"
sleep 1
done
Try it Yourself »
Use trap - INT to go back to the normal behavior.
Report Errors
A trap on ERR runs every time a command fails. $LINENO holds the line number:
Example: Trap ERR
Save this as errors.sh:
#!/bin/bash
trap 'echo "Error on line $LINENO"' ERR
echo "Start"
ls missing.txt 2> /dev/null
echo "End"
Run it:
./errors.sh
Start
Error on line 4
End