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 SIGINTThe 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 dbnameAfter 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 echoing 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