The sha-bang line at the beginning of the script tells your system that this file is a set of commands to be fed to the command interpreter indicated. Immediately following the sha-bang is a path name to the program that interprets the commands in the script.
The #! line in a shell script will be the first thing the command interpreter (sh or bash) sees. Since this line begins with a #, it will be correctly interpreted as a comment when the command interpreter finally executes the script. The line has already served its purpose – calling the command interpreter. If the script includes an additional #! line, then shell will interpret it as a comment.
Of course, the sha-bang (#!) line must be the very first line in the script. Even a blank line above that could change the meaning, and it would then be considered as a comment. However space between #! and path to interpreter should work.
How it works?
Note: These are my assumptions after a series of tests. I haven’t seen this way of explanation in any other sites. I also couldn’t collect any proofs from strace or similar tools.
As soon as your shell find the magic sha-bang line, it feeds your script file as an argument to the command interpreter mentioned there. Here is a simple test script which uses /bin/rm as sha-bang. When you executes the script, it runs successfully (but the commands within the script won’t be executed). The return value of the execution will be 0 (success), but you won’t find your script after that. The /bin/rm would have already deleted it. $ cat test2.sh #!/bin/rm # self destructing script echo hello world $
$ cat test2.sh
# self destructing script
echo hello world
$ ls -l test2.sh
-rwxr–r– 1 root root 27 May 29 20:47 test2.sh
$ echo $?
$ ls -l test2.sh
ls: test2.sh: No such file or directory
You can repeat this test with /bin/more as sha-bang instead of /bin/rm. It will show the script contents (like you do more on the command line), instead of executing the script.