bash myscript.sh runs in bash, but the first line is #!/usr/bin/sh
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.sh
2.
When you run
bash test.sh
it finds bash in /usr/bin/bash
3. 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:
- In fact, it can be any program, it doesn't have to be a shell.
- Actually more like
execl("./test.sh", "/usr/bin/sh", "./test.sh", NULL)
. -
/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).
Related videos on Youtube
Abhijeet
Updated on September 18, 2022Comments
-
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=
.