Bash script: “[[: not found”

bashbash-scripting

This is my code:

#!/bin/bash
if [[ -d ~/viwiki ]]; then
 cd ~/viwiki
else
 mkdir ~/viwiki
 cd ~/viwiki
fi
if ! [[ -d ./log ]]; then
 mkdir log
 mkdir log/log
 mkdir "log/wget"
elif ! [[ -d ./log/log ]]; then
 mkdir log/log
elif ! [[ -d "./log/wget" ]]; then
 mkdir "log/wget"
fi

When running, it has errors:

tuankiet65@UbuntuPC:~$ sh viwik/test2.sh
viwik/test2.sh: 2: viwik/test2.sh: [[: not found
viwik/test2.sh: 8: viwik/test2.sh: [[: not found

How can I fix this?

Best Answer

I'm guessing that if you run

readlink -f $(which sh)

you will not get Bash as return value, but Dash. You have the correct preamble, but that only matters if you run the script as ./test2.sh after making it executable.

Right now you force-run the script via the sh interpreter, which probably is Dash, and the [[]] construct is a Bash specific one.

That's "why?". If you just replace the double brackets with single ones (and change #!/bin/bash to #!/bin/sh, since your script is now only using POSIX functions anyway) it should run as intended.


Demonstration on Debian, with test.sh with contents:

#!/bin/bash
if [[ "string" == "string" ]]; then
    echo This is Bash
fi

this happens:

$ readlink -f $(which sh)
/bin/dash
$ sh test.sh 
test.sh: 2: test.sh: [[: not found
$ bash test.sh 
This is Bash
$ chmod 755 test.sh
$ ./test.sh
This is Bash
Related Question