Bash Script – Why ‘myscript.sh’ Runs in Bash with ‘#!/usr/bin/sh’

bashshellshell-scriptsolaris

I have a script similar following one:

#!/usr/bin/sh

var="ABC"
if [ $var == "ABC" ]
then
   echo True
else
   echo False
fi

Above code does not work in Solaris Sparc and Solaris X64. It is showing == undefined.
Above code works fine If I replace == with =.

Strange thing is If I ran above code without any change by following method it is working.

#bash test.sh

According to my understanding the script should not work even with bash, as at the top of the script I am using #!/bin/sh which does not support the == as the comparison operator.

Can anyone please explain why it does work when I am running the script as mentioned above.

Note: I am aware of that bash does recognize == and =.

Best Answer

The first line of the script is called the #! line (sometimes called the "shebang" line).

It is only used when a script is executed directly, as in

./test.sh

Explanation

When you run an executable, the operating system looks at the first two bytes to tell what type of program it is.

When you run

./test.sh

the operating system sees that the first two bytes of ./test.sh are #!, so it knows the program is a script.

It reads the rest of the line to see which shell1 it should use to run the script. In this case, the rest of the line is /usr/bin/sh, so it runs /usr/bin/sh test.sh2.

When you run

bash test.sh

it finds bash in /usr/bin/bash3. It sees that the first two bytes of /usr/bin/bash are not #!, so it runs /usr/bin/bash test.sh without even looking at the first line of test.sh.

In both cases, sh and bash actually ignore the shebang line because any line beginning with # is a comment. The # only has this magic effect because of the operating system, not the shell.

More info:

Footnotes:

  1. In fact, it can be any program, it doesn't have to be a shell.
  2. Actually more like execl("./test.sh", "/usr/bin/sh", "./test.sh", NULL).
  3. /bin/sh on most Linux systems, but the question was about Solaris.
Related Question