16

This question already has an answer here:

  • What is the function of bash shebang?
  • What is the difference between executing a file using ./file or sh file?
    • How does bash understand it?

marked as duplicate by Dmitry Grigoryev, Toby Speight, Archemar, sam, lgeorget Mar 29 '17 at 15:43

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

10
  • The function of shebang is:

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.

  • What is the different between executing a file using ./file or sh file?

A Bourne shell script that is identified by the path some/path/to/foo, has the initial line,

    #!/bin/sh -x

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 :

  • 5
    Probably worth pointing out that it's the kernel itself that interprets the shebang, rather than bashor something else. – Muzer Mar 29 '17 at 11:14
  • "3) Shell scripts can be set-user-ID." -- That's not exactly common in current times, since the way interpreter scripts are run has some issues that make it hard to have secure setuid scripts. – ilkkachu Mar 29 '17 at 11:42
  • @ilkkachu - correct, thanks! this is part from Ritchie descrption 37 years ago...I'll add a comment about it – Yaron Mar 29 '17 at 11:47
  • @Yaron, oh, I noticed the date. Just worth mentioning that some things have changed in the meanwhile. Also, it's more like "setuid has no effect" on Linux at least. – ilkkachu Mar 29 '17 at 11:51
  • A bunch of this answer is in a blockquote; what's it quoting? Is it one of the two "More Info" links? – Joshua Taylor Mar 29 '17 at 12:55
11

The function of the hashbang is to tell the kernel what program to run as the script interpreter when the file is executed.

Running ./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.

Note that 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 ./script (through exec and the hashbang line), or with bash script (running the bash interpreter manually):

#!/bin/bash -u
echo $1
5

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.

1

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.

It would be interesting if f.ex. a JavaScript interpreter would be able to ignore such a "Javascript shebang" :)

Not the answer you're looking for? Browse other questions tagged or ask your own question.