This question already has an answer here:
- What is the function of bash shebang?
- What is the difference between executing a file using
- How does bash understand it?
This question already has an answer here:
Interpreter directives allow scripts and data files to be used as commands, hiding the details of their implementation from users and other programs, by removing the need to prefix scripts with their interpreter on the command line.
A Bourne shell script that is identified by the path some/path/to/foo, has the initial line,
and is executed with parameters bar and baz as
some/path/to/foo bar baz
provides a similar result as having actually executed the following command line instead:
/bin/sh -x some/path/to/foo bar baz
Note: On 1980 Dennis Ritchie introduced kernel support for interpreter directives:
The system has been changed so that if a file being executed begins with the magic characters #! , the rest of the line is understood to be the name of an interpreter for the executed file. Previously (and in fact still) the shell did much of this job; it automatically executed itself on a text file with executable mode when the text file's name was typed as a command. Putting the facility into the system gives the following benefits. 1) It makes shell scripts more like real executable files, because they can be the subject of 'exec.' 2) If you do a 'ps' while such a command is running, its real name appears instead of 'sh'. Likewise, accounting is done on the basis of the real name. 3) Shell scripts can be set-user-ID.
Note: Linux ignores the setuid bit on all interpreted executables (i.e. executables starting with a #! line).
4) It is simpler to have alternate shells available; e.g. if you like the Berkeley csh there is no question about which shell is to interpret a file. 5) It will allow other interpreters to fit in more smoothly.
More info :
The function of the hashbang is to tell the kernel what program to run as the script interpreter when the file is executed.
./program does exactly that, and requires execute permission on the file, but is agnostic to what type of a program it is. It might be a bash script, an sh script, or a Perl, Python, awk, or expect script, or an actual binary executable. Running
sh program would force it to be run under
sh, instead of anything else.
sh is different from
bash! The latter has a number of advanced features not known by the standard shell. Depending on the system,
sh might be another program, or Bash in compatibility mode, but the result is usually the same: any advanced features are inaccessible.
Bash in itself doesn't understand the hashbang line, but relies on the kernel to read it. On the other hand, the Perl interpreter does also read the hashbang line by itself regardless of how it was started: it does this to pick any command line options set on the hashbang line. Bash doesn't do this.
For example, the following script has different behaviour depending on if it is started as
exec and the hashbang line), or with
bash script (running the bash interpreter manually):
#!/bin/bash -u echo $1
bash itself does not attach any meaning to the shebang line, it only sees it as a comment. When the shell reads a command line, and the command is an external program (not an internal command like
cd), it executes the command using the
execve system call. The kernel then examines what kind of executable the file passed to
execve is by checking the magic number at the start of the file. If the magic number consists of the two bytes 0x23 0x21 (ASCII characters
#!), the kernel assumes they are followed by the absolute path the the interpreter of the script. The kernel then starts the interpreter, passing the script to it.
Well, to be 100% precise, there is not much about a "bash shebang". A shebang can pop up in various forms. It is simply an interpreter indication. So a shebang of, let's say,
#!/usr/bin/perl would f.ex. be a "perl shebang" and indicate the perl interpreter as the interpreter for such a schript. You could then call such a perl script like any shell script directly. The same stands for any other script interpreter. That could be php, or cshell, or prolog, or basic or anything other that interprets text files in some way. And of course that interpreter should be able to ignore the shebang. For bash it is simply a comment line. The same is true for php and perl. I think prolog would choke on that line though.
The shebang should also work seamingless with your own application, as long as this is able to interpret the text, and to ignore the shebang.