Shell script working fine without shebang line? Why?

26,401

Solution 1

shebang line is needed in the file and only if it's meant to be run as executable (as opposed to sh file.sh invocation. It is not actually needed by script, it is for the system to know how to find interpreter.

EDIT: Sorry for misreading the question. If the shebang line is missing or not recognized, /bin/sh is used. But I prefer being explicit about the interpreter.

Note, that this behavior is not universal, IIRC, only some exec* family function do that (not to mention different platforms), so that's another reason to be explicit here.

Solution 2

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.

Solution 3

The POSIX (Single UNIX Specification 4) standard is not helpful:

If the first line of a file of shell commands starts with the characters "#!" , the results are unspecified.

So, the standard implies that if you don't have #! then it should run a POSIX shell. But modern shells are not POSIX compliant. The old Korn Shell 88 (ksh88) ran the Bourne shell (close to a POSIX shell) with no #! line, but ksh93 breaks that, and so does Bash. With both ksh93 and Bash, they run their own shell if no #! line is present.

Despite popular opinion, Bash and Korn shells differ. When you write a shell script you can never be sure what shell you will be run from, or even if it will be run from another shell at all (most programming languages can run other programs). The minute you use something outside of Bourne/POSIX syntax you will be scuppered.

Always use a #! line, don't leave it to chance.

Share:
26,401
Admin
Author by

Admin

Updated on October 24, 2020

Comments

  • Admin
    Admin over 3 years

    I was writing a simple shell script and found out that my shell script doesn't require shebang line

    #!/bin/sh
    

    If I give execute permissions to my script and execute using ./myscript.sh. It runs fine.

    I am using bash shell and /bin/sh is actually pointing to bash.

    lrwxrwxrwx 1 root root /bin/sh -> bash
    

    I know that shebang line is used to tell shell which interpreter to use for your rest of the script.

    If I miss shebang line in perl, give execute permissions and run ./myscript.pl, it doesn't work.

    What's actually happening here? If I use ./, When is shebang line actually needed?