Why do I Get [[: not found When Running a Script?

15

3

I'm trying to write a script that has to check if a file exists. In the console I write

if [[ -a /path/to/file.txt ]]; then echo "not mod"; else echo "mod"; fi

and I get

not mod

but when I write a script to do the same thing:

#!/bin/sh
if [[ -a /path/to/file.txt ]]; then echo "not mod"; else echo "mod"; fi

and then execute the script, I get this:

./ex.sh: 2: [[: not found
mod

I saved the script on the current directory and named it ex.sh, then I made sure it is executable. To call the script I do this:

./ex.sh

Why am I getting this problem? I already tried many things:

if [ -a /home ...

and

if test -a /home ...

Both of them return

13: -a: unexpected operator

Buzu

Posted 2012-01-04T06:01:25.823

Reputation: 171

I was able to make it work, but for that I had to remove the first line (#!/bin/sh) Do you know why this happens? – Buzu – 2012-01-04T06:21:27.680

try #!/bin/bash – kev – 2012-01-04T06:38:57.997

hello kev, I relized that too. I just updated my question. I spent too much time on this, but I'm glad I could solve it. Thanks for your answer. It is indeed, the solution to the problem. – Buzu – 2012-01-04T06:43:08.783

@Kev Please post that as an answer – slhck – 2012-01-04T08:42:19.670

Buzu, @Kev - if you find an answer, post it as an answer below, do not edit the question. – user1686 – 2012-01-04T08:43:04.957

@kev: I edited the question to remove the answer, since all the information is already in the answer you posted. – Keith Thompson – 2012-01-04T21:49:02.530

Answers

10

You are running a script written for bash under sh, which lacks many of the extended syntax features – [[ is a bash builtin command and is not available in sh.

Change #!/bin/sh to #!/bin/bash or to #!/usr/bin/env bash.

kev

Posted 2012-01-04T06:01:25.823

Reputation: 9 972

none of them worked for me :/ im on centos – astroanu – 2015-03-27T06:00:50.010

On some systems, /bin/sh is a symlink to /bin/bash. And it's probably reasonably safe to assume that bash is /bin/bash. – Keith Thompson – 2012-01-04T19:07:09.503

@Keith: It's /bin/bash on most Linux systems, but /usr/pkg/bin/bash on BSDs, or /usr/local/bin/bash if one compiles directly from source. – user1686 – 2012-01-04T19:35:59.017

@grawity: Or wherever else you decide to put it if you compile from source. Ok, good point. Personally, I'd rather edit the shebang for each system than use the /usr/bin/env hack (which uses whichever bash happens to be in the callers $PATH at the moment), but YMMV. (And you can make /bin/bash a symlink -- if you have admin rights and you don't mind messing with /bin.) – Keith Thompson – 2012-01-04T21:36:15.750

@Keith: /usr/local is where autotools decides to put it by default. As far as "personally" goes, I like having several different servers and VMs pull from the same scripts/tools repository, and not needing to re-edit the shebangs on half of them after every commit. – user1686 – 2012-01-05T02:03:37.817

0

Specify bash instead of sh when running the script. I personally noticed they are different under ubuntu 12.10:

bash script.sh arg0 ... argn

Smeterlink

Posted 2012-01-04T06:01:25.823

Reputation: 394