Why use double quotes in a [[ ]] test?

You don't actually need the quotes here. This is one of the very few cases where it is safe to use a variable unquoted. You can confirm this with set -x:

$ var1=""
$ var2="3"
$ set -x
$ if [[ $var1 -eq $var2 ]]; then echo "match!"; else echo "no match!"; fi
+ [[ '' -eq 3 ]]
+ echo 'no match!'
no match!
$ if [[ "$var1" -eq "$var2" ]]; then echo "match!"; else echo "no match!"; fi
+ [[ '' -eq 3 ]]
+ echo 'no match!'
no match!

As you can see above, the quoted and unquoted versions of the test are resolved to the exact same thing by bash. The same should be true for zsh and, I think, any other shell that supports the [[ ]] operator.

Note that this is not the case with the more portable [ ]:

$ if [ $var1 -eq $var2 ]; then echo "match!"; else echo "no match!"; fi
+ '[' -eq 3 ']'
sh: [: -eq: unary operator expected
+ echo 'no match!'
no match!

The [ ] construct, unlike the [[ ]] one, does require quoting.


Some useful links to learn more about when and why quoting is required:

  • Why does my shell script choke on whitespace or other special characters?
  • Security implications of forgetting to quote a variable in bash/POSIX shells
  • When is double-quoting necessary?

Even though the double quotes aren't necessary, reasons to use them are:

  • Good practice/habit: In this case they aren't necessary, but in general double quotes are to avoid unintended word splitting.
  • Because value1 and value2 are variable, and you might not know what they contain. Otherwise you might as well ask, "Why bother with variables instead of checking if [[ 5 -eq 3 ]]? Or taking it further, why bother with the if at all when you already know that 5 isn't equal to 3? It's often better to be defensive. (It's true that word-splitting won't happen in [[, but cases where word-splitting does not happen are rare. Again, see the first point.)

Word splitting.

This example is very improbable, but possible, so if you want to code defensively, cover your tracks with quotes:

$ set -x
$ value1=5
+ value1=5
$ value2=3
+ value2=3
$ [ $value1 -eq $value2 ]
+ '[' 5 -eq 3 ']'

OK, all good so far. Let's throw the wrench into the gears:

$ IFS=456
+ IFS=456
$ [ $value1 -eq $value2 ]
+ '[' '' -eq 3 ']'
bash: [: : integer expression expected

Oops.

$ [ "$value1" -eq "$value2" ]
+ '[' 5 -eq 3 ']'

Ahh.