The parent shell, where you entered ./myscript.sh
, first tried to execve
it, which is where the shebang line would take effect if present. When this works, the parent is unaware of the difference between scripts and ELFs because the kernel takes care of it.
The execve
failed, so an ancient unix compatibility feature, predating the existence of shebang lines, was activated. It guessed that a file which has execute permission but is not recognized as a valid executable file by the kernel must be a shell script.
Usually the parent shell guesses that the script is written for the same shell (minimal Bourne-like shells run the script with /bin/sh
, bash runs it as a bash subprocess), csh does some more complicated guessing based on the first character because it predates shebang too and it needed to coexist with Bourne shell).
You need a shebang line when you know these guesses will be wrong (for example with the shebang is #!/usr/bin/perl
), or when you don't trust the guessing to work consistently, or when the script needs to be runnable by a parent process that is not a shell itself.