jonner jonner - 5 months ago 23
Bash Question

Why do shell script comparisons often use x$VAR = xyes?

I see this often in the build scripts of projects that use autotools (autoconf, automake). When somebody wants to check the value of a shell variable, they frequently use this idiom:

if test "x$SHELL_VAR" = "xyes"; then
...


What is the advantage to this over simply checking the value like this:

if test $SHELL_VAR = "yes"; then
...


I figure there must be some reason that I see this so often, but I can't figure out what it is.

Answer

If you're using a shell that does simple substitution and the SHELL_VAR variable does not exist (or is blank), then you need to watch out for the edge cases. The following translations will happen:

if test $SHELL_VAR = yes; then        -->  if test = yes; then
if test x$SHELL_VAR = xyes; then      -->  if test x = xyes; then

The first of these will generate an error since the fist argument to test has gone missing. The second does not have that problem.

Your case translates as follows:

if test "x$SHELL_VAR" = "xyes"; then  -->  if test "x" = "xyes"; then

It may seem a bit redundant since it has both the quotes and the "x" but it will also handle a variable with spaces in it, without giving that as two arguments to the test command.

The other reason (other than empty variables) has to do with option processing. If you write:

if test "$1" = "abc" ; then ...

and $1 has the value -n or -z or any other valid options to the test command, the syntax is ambiguous. The x at the front prevents a leading dash from being picked up as an option to test.

Keep in mind that this depends on the shell. Some shells (csh for one, I think) will complain bitterly if the environment variable doesn't exist rather than just returning an empty string).

Comments