Does the shebang determine the shell which runs the script?

The shebang #! is an human readable instance of a magic number consisting of the byte string 0x23 0x21, which is used by the exec() family of functions to determine whether the file to be executed is a script or a binary. When the shebang is present, exec() will run the executable specified after the shebang instead.

Note that this means that if you invoke a script by specifying the interpreter on the command line, as is done in both cases given in the question, exec() will execute the interpreter specified on the command line, it won't even look at the script.

So, as others have noted, if you want exec() to invoke the interpreter specified on the shebang line, the script must have the executable bit set and invoked as ./my_shell_script.sh.

The behaviour is easy to demonstrate with the following script:

#!/bin/ksh
readlink /proc/$$/exe

Explanation:

  • #!/bin/ksh defines ksh to be the interpreter.

  • $$ holds the PID of the current process.

  • /proc/pid/exe is a symlink to the executable of the process (at least on Linux; on AIX, /proc/$$/object/a.out is a link to the executable).

  • readlink will output the value of the symbolic link.

Example:

Note: I'm demonstrating this on Ubuntu, where the default shell /bin/sh is a symlink to dash i.e. /bin/dash and /bin/ksh is a symlink to /etc/alternatives/ksh, which in turn is a symlink to /bin/pdksh.

$ chmod +x getshell.sh
$ ./getshell.sh 
/bin/pdksh
$ bash getshell.sh 
/bin/bash
$ sh getshell.sh 
/bin/dash

Yes it does. By the way it is not a silly question. A reference for my answer is here. Starting a Script With #!

  • It is called a shebang or a "bang" line.

  • It is nothing but the absolute path to the Bash interpreter.

  • It consists of a number sign and an exclamation point character (#!), followed by the full path to the interpreter such as /bin/bash.

    All scripts under Linux execute using the interpreter specified on a first line Almost all bash scripts often begin with #!/bin/bash (assuming that Bash has been installed in /bin) This ensures that Bash will be used to interpret the script, even if it is executed under another shell. The shebang was introduced by Dennis Ritchie between Version 7 Unix and 8 at Bell Laboratories. It was then also added to the BSD line at Berkeley .

Ignoring An Interpreter Line (shebang)

If you do not specify an interpreter line, the default is usually the /bin/sh. But, it is recommended that you set #!/bin/bash line.


In fact, if you take it consequently, the executable noted in the shebang line, is just an executable. It makes sense to use some text interpreter as executable, but it is not necessary. Just for clarification and demonstration, i made a rather useless test:

#!/bin/cat
useless text
more useless text
still more useless text

Named the file test.txt and set the exectuable bit chmod u+x test.txt, then "called" it: ./test.txt. As expected, the contents of the file is output. In this case, cat does not ignore the shebang line. It simply outputs all lines. Any useful interpreter should thus be able to ignore this shebang line. For bash, perl and PHP, it is simply a comment line. So yes, these ignore the shebang line.