Difference between quoting variables in shell script "if" statements?

If the value of $FOO is a single word that doesn't contain a wildcard character \[*?, then the two are identical.

If $FOO is unassigned, or empty, or more than one word (i.e., contains whitespace or $IFS), then the unquoted version is a syntax error. If it happens to be just the right sequence of words (such as 0 -eq 0 -o false), the result could be arbitrary. Therefore, it is good practice to always quote variables in shell scripts.

Incidentally, "true" does not need to be quoted.


To illustrate what problems it might cause, here a few examples.

Let's say we have two variables as follow:

FOO="some value"
BAR="some value"

Now we have two variables holding exactly the same string/value. If we did some if statements to test the result, in your case:

if [ $FOO = "$BAR" ]; then echo "match"; else echo "no match"; fi

At this point you will get bash: [: too many arguments. The unquoted $FOO holds now three values, namely '[ , some , value'. [ test keyword doesn't know what to execute because it is expecting the first or second argument to be an operator.

When we quote "$FOO" we explicitly tell if to look at the right values where no word splitting takes place.

Another example:

my_file="A random file.txt"
  • doing rm $my_file means removing 'A' 'random' 'file.txt' which makes it three files.
  • doing rm "$my_file" will remove "A random file.txt" which makes one file.

Hope I've not confused you with these examples.