Why is set -eu not working?

If you write shell scripts, you may be familiar with the following header (or some variation) in your script:

set -euo pipefail

As noted in Use Bash Strict Mode (Unless You Love Debugging) this allows us to:

  • set -e: exit the script on errors
  • set -u: error when undefined variables are used
  • set -o pipefail: fail when piped commands fail

I recently hit an issue where this didn't work where I expected it to, which was very surprising πŸ˜…

For a minimal reproduction, let's use:

#!/bin/bash
set -euo pipefail

export HI=$(echo $HELLO)
echo $HI

echo "END"

When we run this, we should expect to see an error and END not being printed, right? Well no, we actually see:

a.bash: line 4: HELLO: unbound variable

END

It turns out that this is a documented issue, and has a Shellcheck warning, "Declare and assign separately to avoid masking return values" for this (which I have actually seen before, but haven't ever addressed 🫣).

Instead, if we make the following change to make sure we export separately to defining the variable:

diff --git a.bash new
index dd353d3..bae1789 100644
--- a
+++ b
@@ -1,7 +1,8 @@
 #!/bin/bash
 set -euo pipefail

-export HI=$(echo $HELLO)
+HI=$(echo $HELLO)
+export $HI
 echo $HI

 echo "END"

We now get the correct result (and an exit code):

a.bash: line 4: HELLO: unbound variable

Written by Jamie Tanna's profile image Jamie Tanna on , and last updated on .

Content for this article is shared under the terms of the Creative Commons Attribution Non Commercial Share Alike 4.0 International, and code is shared under the Apache License 2.0.

#blogumentation #command-line #bash.

This post was filed under articles.

Interactions with this post

Interactions with this post

Below you can find the interactions that this page has had using WebMention.

Have you written a response to this post? Let me know the URL:

Do you not have a website set up with WebMention capabilities? You can use Comment Parade.