This question already has an answer here:
-
Why do shell script comparisons often use x$VAR = xyes?
7 answers
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
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 [ "" != "" ]
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.
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.