Learn Docker With My Newest Course

Dive into Docker takes you from "What is Docker?" to confidently applying Docker to your own projects. It's packed with best practices and examples. Start Learning Docker →

Executing Code after an Error Occurs with Bash When Using Set e

blog/cards/executing-code-after-an-error-occurs-with-bash-when-using-set-e.jpg

I'm sure you're using set -e in your scripts, and often times it's useful to execute some code if an error occurs. Here's how.

Quick Jump: A Real World Use Case | Trapping Errors with Bash

In case you’ve never heard of or used set -e before, it’s something you can add to a Bash script which tells Bash to immediately exit if any part of your script throws an error.

set -e is something you would put at the top of your script, such as:
#!/bin/bash

set -e

echo "Hello World"

(exit 1)

echo "This will never execute"

In the above case, the second echo command will never execute because set -e will halt the script on the (exit 1) line. We’re using (exit 1) here to emulate an error that would likely happen in a real world script.

If we didn’t have set -e at the top of the file, then both echo commands would get output to your terminal because Bash wouldn’t halt the script on the error.

Using set -e is really useful because if a part of your script fails, chances are you want everything to halt, because later parts of your script might depend on everything before it running successfully.

A Real World Use Case

I had this situation come up recently while creating my next course. One of the things we’ll do in the course is test an Ansible run inside of a Docker container.

One of the things that the test.sh script does is stop the container after the Ansible run, but I was noticing that the script never ran the stop container function if the Ansible test failed because Ansible returned a non-0 exit code which triggered set -e.

This was a huge problem because after a few test script runs, I ended up with a bunch of running containers that were using quite a few resources. Eventually Docker for Windows would crash.

What I really wanted to do was something like “run the test script, but no matter what, make sure the container is stopped whether or not Ansible ran successfully”.

Trapping Errors with Bash

Lucky for us, the author of Bash thought of how to solve this. If you want to follow along, create a test.sh file and then chmod +x test.sh it so you can run it.

Trapping errors and executing a custom function:
#!/bin/bash

set -e

do_something() {
  echo "This will always execute"
}

trap "do_something" ERR

echo "Hello World"

return

do_something
If you run the above script, you’ll get this output:
Hello World
./test.sh: line 13: return: can only `return' from a function or sourced script
This will always execute

That’s because you can’t use the return keyword like that. You can only use it when it’s inside of a function. I’m just using it here as an example of how to raise an error with Bash.

But as you can see, the “This will always execute” line was returned. That’s because the return keyword threw an error and we trapped that error and told Bash to call the do_something function.

If you comment out the return line and run the script again, it will output both “Hello World” and “This will always execute” but this time there was no error, so it just called do_something as usual.

Have you used this strategy before? Let me know in the comments below.

Never Miss a Tip, Trick or Tutorial

Like you, I'm super protective of my inbox, so don't worry about getting spammed. You can expect a few emails per month (at most), and you can 1-click unsubscribe at any time. See what else you'll get too.


Comments