7

In various guides and scripts I come across people tend to use different syntax of if statements. What's the difference and what are best practices? I believe all the following statements, and many more variants, will return true:

bar="foo"
if [ "foo" = "foo" ]
if [[ "foo" == $bar ]]
if [ "foo" = "$bar" ]
if [[ "foo" = "$bar" ]]
if [[ "foo" -eq $bar ]]
Jacob Rask
  • 22,804
  • 8
  • 38
  • 36
  • 1
    possible duplicate of [bash: double or single bracket, parentheses, curly braces](http://stackoverflow.com/questions/2188199/bash-double-or-single-bracket-parentheses-curly-braces) – Greg Hewgill Aug 07 '10 at 13:09
  • Read http://mywiki.wooledge.org/BashGuide http://mywiki.wooledge.org/BashFAQ http://mywiki.wooledge.org/BashPitfalls – Philipp Aug 07 '10 at 14:01

3 Answers3

5

As I understand it

= expects strings

-eq expects integers

"$bar" is for literal matches, i.e. z* may expand but "z*" will literally match the wildcard char.

The difference between [] and [[]] is that in the latter word splitting and path name expansion are not done, but are in the former.

Plus [[]] allows the additional operators :

&& (AND), || (OR), > (String1 lexically greater than String2), < (String1 lexically less than String2)

The == comparison operator behaves differently within a double-brackets test than within single brackets.

[[ $a == z* ]] # True if $a starts with an "z" (pattern matching).

[[ $a == "z*" ]] # True if $a is equal to z* (literal matching).

[ $a == z* ] # File globbing and word splitting take place.

[ "$a" == "z*" ] # True if $a is equal to z* (literal matching).

Check out http://tldp.org/LDP/abs/html/comparison-ops.html for more info

lucas1000001
  • 2,740
  • 1
  • 25
  • 22
  • Minor correction/clarification: `=` and `==` do exactly the same thing (i.e. they both do pattern matching within `[[ ]]`) except that some implementations of `[` don't support `==`. Basically, the only reason to use `==` is that it's familiar from other languages. Also, `[` does support string comparisons with `<` and `>`, you just have to escape them or they'll be parsed as I/O redirections: `[ string1 \< string2 ]` for example. – Gordon Davisson Aug 08 '10 at 04:38
3

[ is a bash builtin, [[ is a bash keyword. Best practice is to always use [[ if the script doesn't have to be compatible with other shells (e.g., if it starts with #!/bin/bash), and use [ only for compatibility with the Bourne shell. See http://mywiki.wooledge.org/BashFAQ/031.

Philipp
  • 48,066
  • 12
  • 84
  • 109
2

I recommend case/esac.

case "$foo" in
  "bar" ) echo "bar";;
  *) echo "not equal";;
esac

No fretting about different syntax.

ghostdog74
  • 327,991
  • 56
  • 259
  • 343