32

I'm very new to bash scripting and am running into an issue when using double brackets. I can't seem to get them to work at all in Ubuntu Server 11.10. My script below is in if_test.sh.

#!/bin/bash

if [[ "14"=="14" ]]; then 
    echo "FOO"
fi

When I run this simple shell script the output I get is: if_test.sh: 5: [[: not found

It seems that I'm running GNU bash version 4.2.10 after running bash --version from the terminal. Any help would be greatly appreciated. Thanks!

lots_of_questions
  • 1,109
  • 3
  • 16
  • 24
  • BTW, without the spaces, this isn't comparing `14` to `14`, it's checking if the string `14==14` is empty. It would give the exact same result with `[[ "11"=="99" ]]`, since that string isn't empty either. – Charles Duffy Jan 30 '18 at 23:19

3 Answers3

47

The problem lies in your script invocation. You're issuing:

$ sudo sh if_test.sh

On Ubuntu systems, /bin/sh is dash, not bash, and dash does not support the double bracket keyword (or didn't at the time of this posting, I haven't double-checked). You can solve your problem by explicitly invoking bash instead:

$ sudo bash if_test.sh

Alternatively, you can make your script executable and rely on the shebang line:

$ chmod +x if_test.sh
$ sudo ./if_test.sh

Also note that, when used between double square brackets, == is a pattern matching operator, not the equality operator. If you want to test for equality, you can either use -eq:

if [[ "14" -eq "14" ]]; then 
    echo "FOO"
fi

Or double parentheses:

if (( 14 == 14 )); then 
    echo "FOO"
fi
Frédéric Hamidi
  • 258,201
  • 41
  • 486
  • 479
9

My answer doesn't apply to @lots_of_questions's question specifically, but you can also run into this problem if you have the wrong specifier at the top of your script:

#!/bin/sh
if [[ ... ]]
...

You should change that to

#!/bin/bash
if [[ ... ]]
...
Cory Klein
  • 51,188
  • 43
  • 183
  • 243
6

Since you are new to scripting, you may be unaware that [[ is a bashism. You may not even know what a bashism is, but both answers given so far are leading you down a path towards a stunted scripting future by promoting their use.

To check if a variable matches a string in any flavor of Bourne shell, you can do test $V = 14 If you want to compare integers, use test $V -eq 14. The only difference is that the latter will generate an error if $V does not look like an integer. There are good reasons to quote the variable (test "$V" = 14), but the quotes are often unnecessary and I believe are the root cause of a common confusion, since "14"=="14" is identical to "14==14" where it is more obvious that '==' is not being used as an operator.

There are several things to note: use a single '=' instead of '==' because not all shells recognize '==', the [ command is identical to test but requires a final argument of ] and many sh coding guidelines recommend using test because it often generates more understandable code, [[ is only recognized by a limited number of shells (this is your primary problem, as your shell does not appear to recognize [[ and is looking for a command of that name. This is surprising if your shebang does indeed specify /bin/bash instead of /bin/sh).

Eduardo Ivanec
  • 11,668
  • 2
  • 39
  • 42
William Pursell
  • 204,365
  • 48
  • 270
  • 300