set -u usage not working as expected

From "man Bash":

A parameter is set if it has been assigned a value. The null string is a valid value. Once a variable is set, it may be unset only by using the unset builtin command.

When you do testing2= you are setting the variable to the null string.

Change that to unset testing2 and try again.


The set -e does not help in this case as an assignment never has an exit code of 1. Try this to see that the last command executed (the assignment) has an exit code of 0, or read this question:

$ false; a=""; echo $?
0

And I also believe that the use of set -e is more a problem that a solution.

What may get an error with the use of unset variables is set -u:

#!/bin/bash
set -u
testing="This works"
echo ${testing}
unset testing2
echo ${testing2}
testing3="This should not appear"
echo ${testing3}

Will output:

$  ./script.sh
This works
./script.sh: line 9: testing2: unbound variable

testing2= sets the testing2 variable to an empty string; the variable actually is set.

However if you were to run echo $testing99 in an interactive Bash shell (without setting errexit, i.e., set -e), you would get an error:

bash: testing99: unbound variable

Aside

While testing scripts just now, I discovered that an interactive shell does not always exit when attempting to expand a variable that hasn’t been set while a non-interactive shell (running a shell script) always exits. According to the POSIX man page for set:

-u The shell shall write a message to standard error when it tries to expand a variable that is not set and immediately exit. An interactive shell shall not exit.

An interactive Bash shell won’t exit unless errexit has also been set. On the other hand, an interactive dash shell won’t exit – even if set -e has previously been run.