Bash Tip - The importance of testing that variables are defined.

Posted by Fred C (W6BSD) on Oct 16 2012

When writing code it's important to make sure all the variables are defined. Using an undefined variable can lead to all sorts of problems. Your program may fail randomly or run commands with unexpected results. Almost all languages raise an error when the program tries to access a variable that does not exist. Unfortunately this is not the case with shell. By default shell interprets an undefined variable as an empty variable.

For example C and Python raise an error when you try to reference an undefined variable.

fred:~$ gcc test.c
test.c: In function `main':
test.c:2: error: `greetings' undeclared (first use in this function)

:::text
fred:~$ python -c 'print greetings'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
NameError: name 'greetings' is not defined

Shell (in our case bash) just returns an empty string.

fred:~$ echo "Directory: $app_dir"
Directory:

In the previous example there is no severe consequences for trying to print a variable that doesn't exists. But what will happen if somewhere in your code you have a line with the following code: rm -fr ${app_dir}/var? Instead of removing the var directory in your application, the system directory /var will disappear. That's why it is always important to have your bash program test the variables before using them.

[ ! -z ${app_dir} ] && { rm -fr ${app_dir}/var; } || {
  echo "Undefined variable \$app_dir";
  exit 1; }

You can strengthen your programs even more by making sure bash raise an error every time an undefined variable is accessed by calling bash with the -u option, or by setting the option nounset at the beginning of your program.

  • set -o nounset will turn on the check
  • set +o nounset will turn off the check

Using the -u argument:

#!/bin/bash -u
echo $1

Or using set

#!/bin/bash
set -o nounset
echo $1

Once executed this code will exit printing an error.

fred:~$ ./var-test.sh
./var-test.sh: line 3: $1: unbound variable

Conclusion

It is always important to check that the variables are defined in all your programs. For shell scripts this is even more important. A shell script often starts as a quick hack, but after few month and different people modifying it, it can evolve to a few hundred lines program that is part of you company standard toolset.


 Bash      Sys Admin