bash myscript.sh runs in bash, but the first line is #!/usr/bin/sh

5,929

Solution 1

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.

Solution 2

Running the script with bash (running bash test.sh) means that the script is interpreted with bash, not the Bourne shell (/bin/sh). That's why it works. Bash ignores the #!/bin/sh because it is a comment. It's only your OS's program loader that starts /bin/sh if you run the shell script without bash (running ./test.sh for example).

Share:
5,929

Related videos on Youtube

Abhijeet
Author by

Abhijeet

Updated on September 18, 2022

Comments

  • Abhijeet
    Abhijeet over 1 year

    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 =.