Sign up ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

I'm testing a simple script and I'm wondering why it works fine when executed from directory: ./ but when I try with "sh" command sh it's not working: 3: [[: not found 7: [[: not found


#!/usr/bin/env bash

if [[ $1 = one ]]
        printf "%b" "two\n" >&2
        exit 0
elif [[ $1 = two ]]
        printf "%b" "one\n" >&2
        exit 0
        printf "%b" "Specify argument: one/two\n"
        exit 1
share|improve this question

2 Answers 2

up vote 15 down vote accepted


sh is a different program than bash.


The problem is that the Bourne shell (sh) is not the Bourne Again shell (bash). Namely, sh doesn't understand the [[ pragma. In fact, it doesn't understand [ either. [ is an actual program or link to /bin/test (or /usr/bin/[, /usr/bin/test).

$ which [
$ ls -lh /bin/[
-r-xr-xr-x  2 root  wheel    42K Feb 29 17:11 /bin/[

When you execute your script directly through ./, you're calling the script as the first argument to the program specified in the first line. In this case:

#!/usr/bin/env bash

Often, this is directly the interpreter (/bin/bash, or any number of other script interpreters), but in your case you're using env to run a program in a modified environment -- but that follow argument is still bash. Effectively, ./ is bash

Because sh and bash are different shells with different syntax interpretations, you're seeing that error. If you run bash, you should see what is expected.

More info

Others have pointed out in comments that /bin/sh can be a link or other shell. Historically, sh was the Bourne shell on the old AT&T Unix, and in my mind the canonical descent. However, that is different in BSD variations and has diverged in other Unix based systems and distributions over time. If you're really interested in the inner workings (including how /bin/sh and /bin/bash can be the same program and behave totally differently), read the following:

SuperUser: What is the difference between bash and sh

Wikipedia: Bourne shell

share|improve this answer
Also, sh is not always the Bourne shell, but usually implies compatibility with POSIX sh (based largely on Bourne). On Ubuntu, for instance, /bin/sh is symlinked to /bin/dash. – bonsaiviking Jun 21 '12 at 22:12
sh is bash on CentOS and dash on Ubuntu. – Iain Jun 21 '12 at 22:14

As noted: /bin/sh typically (though not always) invokes a POSIX-compliant Bourne shell. Bash is Not Bourne.

Bash will attempt to emulate Bourne when invoked as 'sh' (as when /bin/sh symlinks or links to /bin/bash), or if $POSIXLY_CORRECT is defined in the invoking environment, when invoked with the --posix invocation option, or when 'set -o posix' has been executed. This enables testing a Bourne shell script / command for POSIX compliance.

Alternately, invoke scripts / test commands with a known POSIX-compliant shell. 'dash' is close, the Korn shell (ksh) IIRC offers a POSIX compliant option as well.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.