tags:

views:

68

answers:

3

I'm peeking through some shell scripts - what's the purpose of the x in the comarison shcu as

 if [ "x$USER" != "x$RUN_AS_USER" ]; then
        su - $RUN_AS_USER -c "$CATALINA_HOME/bin/startup.sh"
 else
        $CATALINA_HOME/bin/startup.sh
 fi
+1  A: 

If the variables are an empty string or uninitialized, without the x the if would look like this after the variable substitution:

 if [ != ]; then

and thus it would fail because the operands are missing. With the x, the if looks like this:

 if [ x != x]; then

which is syntactically valid.

Cristian Ciupitu
+7  A: 

It's a trick to ensure you don't get an empty string in the substitution if one of the variables is empty. By putting x on both sides it's the same as just comparing the variables directly but the two sides will always be non-empty.

It's an old kludge which made more sense when scripts were written as:

if [ x$USER != x$RUN_AS_USER ]

There if you just had $USER and it were empty then you could end up with

if [  != root ]   # Syntax error

With the x you get this, which is better:

if [ x != xroot ]

However, when the variables are quoted the x is unnecessary since an empty string in quotes isn't removed entirely. It still shows up as a token. Thus

if [ "$USER" != "$RUN_AS_USER" ]   # Best

is the best way to write this. In the worst case with both variables empty you'd get this which is a valid statement:

if [ "" != "" ]
John Kugelman
And it doesn't matter if '$USER' is '-f' because there are three arguments to test, so it must be an inequality and not a file test operation.
Jonathan Leffler
+5  A: 

The problem is related to odd-ball values, as Cristian Ciupitu suggests, but empty strings aren't the problem (at least, not when the value as a whole is quoted). The issue is related to names that could be confused with operators to test (or '['; on some systems, there really is a program /bin/[). The POSIX standard has almost made this redundant, but consider what happens if '$USER' is '-f', '$RUN_AS_USER' is empty and the x's and quotes are not used.

if [ -f != ]
then : someone has a file called '!='
else : they don't have a file called '!='
fi

By using the quotes and the leading x, this sort of misinterpretation is avoided.

Jonathan Leffler