Tux the PenguinIf you are in the middle of running your nice and juicy, newly typed up bash script and it throws up its arms with the following error message:

[: =: unary operator expected.

…chances are pretty good that you’ve introduced the possibility of raising an empty variable in your script.

Let’s use the following code for our example:

if [ $number = “1” ]; then
echo “Number equals 1”
echo “Number does not equal 1”

(Notice that we’ve commented out number=1 and replaced it instead with number=, which is perfectly valid and the correct way of assigning a null value to a variable)

Running this code will result in:

[craig]$ ./emptyvariable.bash
/emptyvariable .bash: [: =: unary operator expected.
Number does not equal 1

If you look carefully at the error report, you’ll notice that bash is actually complaining about something to do with an opening “[” character, even though it is actually running through the entire script and producing the correct result of “Number does not equal 1”.

Of course, if we comment out the number= and replaced it with the number=1 line, the script runs through just perfectly without an warning messages, meaning that the error must lie with that line, right?

Well actually no.

Remember that “[” is the abbreviation for the built-in test shell, meaning that the error that is being thrown lies in our if statement rather than our variable declaration. To understand what is happening here, we need to try and see what the shell is seeing.

Remembering to note that the shell spends a heck of lot of its time substituting text for a living, if we look at the working example we see that the shell would have substituted 1 for $number thanks to the prior rule that set $number=1. In other words, the shell would have ended up with this line:

if [ 1 = “1”]; then

However, if we now take our first, broken example, the shell’s substitution would end up with this:

if [ = “1”]; then

…which is obviously an error. This pretty much explains the rest then. The error is occurring because “=” is a binary operator, in other words it expects two items on which to operate – one on either side of it. The shell obviously recognises this and responds by telling us we should rather be using a unary operator in this instance (like “!” for example), because this operates on only a single item.

In order to fix this problem, change the if statement line to reflect:

if [ “$number” = “1”]; then

…which would then result in the following after substitution occurs:

if [ “” = “1” ]; then

Obviously this now correctly specifies what we are trying to test for and the shell is happy with what we’re trying to achieve. In other words, always remember to take empty variable instances into consideration when writing a script!