It’s a (Bash) Trap!

Published June 26, 2025 by Tom
Bash
It’s a (Bash) Trap!

Let me tell you about a little command in Bash that’s saved my backside more times than Git stash has saved half-finished Friday night code commits: it’s called trap. Sounds like something Indiana Jones might fall into, and honestly, it behaves a bit like that too. Except instead of spikes and dramatic theme music, it just helps your shell scripts not explode in a pile of silent errors and broken dreams.

So what is trap, exactly?

In simple terms: trap lets you catch signals (like CTRL+C, aka SIGINT) or errors (like when you forget to check if a directory exists before deleting it… not that I’ve ever done that), and respond to them with grace. Or at least mild dignity.

Imagine you’re running a script that backs up files, renames a few things, syncs to Dropbox, sacrifices a goat to the cloud gods, and deletes some temp stuff. Then your cat walks across your keyboard mid-script and hits CTRL+C. Without trap, your script bails halfway through, leaving you with half a goat, no backup, and a strong desire to rethink your life choices.

With trap, you can catch that interruption and say, “Oi! Clean up first!” before exiting.

Example time

#!/bin/bash

cleanup() {
echo "Tidying up... don't mind me."
rm -f /tmp/my_temp_file
}

trap cleanup EXIT

touch /tmp/my_temp_file
echo "Doing important things..."
sleep 10

This lil’ script touches a temp file, then chills out for 10 seconds. If you interrupt it with CTRL+C, or it finishes naturally, it runs the cleanup function before exiting.

This is like finally learning to leave the pub with your coat, wallet, and dignity intact. Rare, but possible.


But I Use Laravel, Not Shell Scripts?

Same, mate. But here’s the thing — you probably run shell scripts more than you think:

  • You’re deploying with Envoyer? There’s a Bash script hiding in there.
  • Running artisan queue:work as a daemon?
  • Doing artisan migrate --force in CI/CD?
  • Building a custom Laravel Forge deploy script?
  • Using Bash to run scheduled Laravel commands in Docker or Cron?

All Bash. All potential chaos. All candidates for a cheeky trap.

Picture this:

You’ve got a deploy.sh script. It pulls the latest code, runs migrations, clears caches, warms up some views, maybe restarts the queue worker. It all works. Until someone hits CTRL+C halfway through. Now your queue workers are still running code from the old release, but the database schema has changed. Good luck debugging that one at 2am.

Instead, slap in a trap:

cleanup() {
echo "Rolling back deployment..."
# Remove symlink to new release
# Re-point to previous release
# Maybe alert yourself on Slack
}
trap cleanup INT TERM

Now when your deploy dies mid-flight, it at least leaves things in a state where you don’t have to swear at Redis.

Or maybe you’re running tests locally with a custom script — database seeded, environment booted — then halfway through, you realise you forgot to --filter the test you actually wanted. CTRL+C to cancel. But wait — your local DB is now full of test garbage. Again, trap can step in and handle cleanup, like dropping your test database or rolling back transactions.

Final thoughts

trap is like that one reliable friend who turns off the oven when you fall asleep during Bake Off. Underappreciated. Uncool. But essential.

Laravel might live in PHP, but the ecosystem around it runs on Bash. So next time you’re scripting anything remotely important — a deploy script, a Docker entrypoint, a CI/CD step — use trap. Your future self (and your database) will thank you.

Now if only we could trap bugs in Laravel before they hit production…