Why is set -eu
not working?
This post's featured URL for sharing metadata is https://www.jvt.me/img/profile.jpg.
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 errorsset -u
: error when undefined variables are usedset -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