Bash’s trap
command is used to catch and react to signals sent to your shell. It’s similar to an event listener in the browser, or a pubsub topic subscriber.
The typical use case is to run some kind of cleanup command when a process terminates, like this:
trap cleanup_job TERM SIGINT
The command above will run cleanup_job
when it receives a TERM
or SIGINT
(ctrl-c).
I’ve only needed the trap
command a few times, and I’ll go through one example here.
Using trap to kill a background task
At my day job, we have a two-part script to connect to remote databases. The script starts a proxy service and then uses that proxy to query a remote database directly.
We need this workflow most often in emergencies, so it’s setup to be run as a single command for ease-of-use, like so:
# connect_to_db.sh
echo "Starting Sql Proxy"
# Use bash '&' to run this in the background
cloud_sql_proxy -instance=lots-of-info-here &
# Store the process id of the proxy command
PROXY_PID=$!
# Kill the proxy process when we exit the postgres shell
# This won't actually run until it hears a TERM or SIGINT
trap "echo '===Terminating sql proxy $PROXY_PID===' && kill $PROXY_PID" TERM SIGINT
echo "connecting to DB"
# Not the prettiest, but has never failed us
sleep 3
# Connect to the database through the proxy
PGPASSWORD=secret psql -h 127.0.0.1 -p 1337 -U username -d dbname
After running connect_to_db.sh
, I’m dropped into a psql shell in the remote database. As long as I’m in there the proxy keeps running, but as soon as I end my connection the trap
command will receive its TERM
or SIGINT
signal-depending on how I exited-and it’ll react by echo
ing a line in the terminal and running kill $PROXY_PID
.
The script above also makes use of a few other bash operators and parameters like &
, &&
, and $!
. I’ve added a few links below with more information on each of those.
Helpful Links
- Lots of detail about trap – The Linux Documentation Project
- What’s the meaning of $! in bash
- Ampersands on the command line
- Bash control operators (&, &&) – GNU docs
- Bash special parameters (like $!) – GNU docs