1

In some bash codes, I see an extra character is added before the string comparison. Can somebody explain the reason?

if [ "x$VAR" = "xString" ]; then
...
fi

3 Answers3

3

You'll see that to protect against the possibility of the variable being unset. Consider, for example:

if [ $x = "hi" ]; then echo $x; fi

If x is set to hi, then the behavior is:

$ if [ $x = "hi" ]; then echo $x; fi
hi
$

However, if x is unset, then you get an error because there's nothing on the left of the =:

$ if [ $x = "hi" ]; then echo $x; fi
zsh: parse error: condition expected: =

Adding quotes resolves the problem:

$ if [ "$x" = "hi" ]; then echo $x; fi
$

Also, adding some non-blank value resolves the problem:

$ if [ x$x = "xhi" ]; then echo $x; fi
$ x=hi
$ if [ x$x = "xhi" ]; then echo $x; fi
hi
$
Andy Dalton
  • 13,993
  • 1
    No, that x prefix is not what it's about [ x$x = "xhi" ] is about as wrong as [ $x = hi ]. as the quotes are in the wrong place. [ "$x" = hi ] is correct with a POSIX compliant [ but breaks with some values of $x such as ! or ( in old, broken implementations of [, hence the prefix. – Stéphane Chazelas Nov 04 '20 at 06:27
  • @StéphaneChazelas thank you for the clarification. Your answer to the linked question is very clear -- I learned something new. – Andy Dalton Nov 07 '20 at 01:00
1

You have probably seen that without the quotes, like [ x$VAR = xstring ]

If for some reason VAR has not been defined, then it will not expand to anything, and the script interpreter will give an error, like -bash: [: =: unary operator expected. (I mean, the interpreter will see [ = string ] and protest against it.) By adding an extra char on both sides, you guarantee that the "nothing" will be "something", and yet the = will still hold. With quotes though, you'll not get such an error, but many people just add an extra char -- out of habit, and don't pay much attention to quotes.

Pourko
  • 1,844
  • 2
    No, that x prefix is not what it's about [ x$x = "xhi" ] is about as wrong as [ $x = hi ]. as the quotes are in the wrong place. [ "$x" = hi ] is correct with a POSIX compliant [ but breaks with some values of $x such as ! or ( in old broken implementations of [, hence the prefix. – Stéphane Chazelas Nov 04 '20 at 06:28
  • @Stéphane Chazelas: Yes, that too. Good point! Although, I wouldn't say "not what it's about". (I mean, guarding against undefined variable, when there are no quotes) – Pourko Nov 04 '20 at 06:37
0

It's done to keep the string from being empty, even if $VARIABLE is empty. The bash construct

if [  $var = Y ]

misbehaves if $var is "".

waltinator
  • 4,865
  • 1
    The way you put it in quotes, it won't "misbehave". :-) – Pourko Nov 03 '20 at 23:03
  • @porku: Thanks, fixed. My fingers have "Quote all variables" as a built-in. – waltinator Nov 03 '20 at 23:35
  • 2
    No, that x prefix is not what it's about [ x$x = "xhi" ] is about as wrong as [ $x = hi ]. as the quotes are in the wrong place. [ "$x" = hi ] is correct with a POSIX compliant [ but breaks with some values of $x such as ! or ( in old broken implementations of [, hence the prefix. – Stéphane Chazelas Nov 04 '20 at 06:28