#! line is used before the script is run, then ignored when the script runs.
You're asking what the difference is between a shebang line and an ordinary comment.
A line starting with
#! is just as much a comment as any other line that starts with
#. This is true if the
#! is the first line of the file, or anywhere else.
#!/bin/sh has an effect, but it is not read by the interpreter itself.
# is not a comment in all programming languages but, as you know, it's a comment in Bourne-style shells including
bash (as well as most non-Bourne-style shells, like
csh). It's also a comment in Python. And it is a comment in a variety of configuration files that are not really scripts at all (like
Suppose a shell script begins with
#!/bin/sh. That is a comment, and the interpreter (the shell) ignores everything on the line after the
The purpose of a
#! line is not to give information to the interpreter. The purpose of the
#! line is to tell the operating system (or whatever process launches the interpreter) what to use as the interpreter.
If you invoke the script as an executable file, for example, by running
./script.sh, the system consults the first line to see if begins with
#!, followed by zero or more spaces, followed by a command. If it does, it runs that command with the name of the script as its argument. In this example, it runs
/bin/sh script.sh (or, technically,
If you invoke the script by explicitly calling the interpreter, the
#! line is never consulted. So, if you run
sh script.sh, the first line has no effect. If
script2.sh's first line is
sh script2.sh will not try to open the script in
You'll notice that in neither case does the script's extension (
.sh), if it has one, impact how it is run. In a Unix-like system, this doesn't ordinarily affect how the script is run. On some other systems, like Windows, the
#! shebang line might be ignored entirely by the system, and the extension might determine what runs the scripts. (This doesn't mean you need to give your scripts extensions, but it is one of the reasons why if you do, they should be correct.)
#! was chosen to serve this purpose precisely because
# begins a comment. The
#! line is for the system, not the interpreter, and it should be ignored by the interpreter.
Shebang Line for Bash Scripts
You (originally) said you use
bash scripts. You should only do that if the script doesn't require any of
sh needs to be able to run the script.
sh is not always a symlink to
bash. Often, including on all remotely recent Debian and Ubuntu systems,
sh is a symlink to
Shebang Line for Python Scripts
You also said (in the first version of your question, before editing) that you start your Python scripts with
#!/bin/sh read by the interpretor. If you mean that literally, then you should definitely stop doing that. If
hello.py begins with that line, running
/bin/sh read by the interpretor hello.py
/bin/sh will try to execute a script called
by the interpretor hello.py as its arguments),
read will (hopefully) not be found, and your Python script will never be seen by a Python interpreter.
If you're making this mistake but not having the problem I'm describing, you're probably invoking your Python scrips by explicitly specifying the interpreter (e.g.,
python hello.py), causing the first line to be ignored. When you distribute your scripts to others, or use them a long while later, it may not be clear that this is necessary for them to work. It's best to fix them now. Or at least remove the first line entirely, so that when they fail to run with
./ the error message will make sense.
For Python scripts, if you know where the Python is (or is going to be), you can write the
#! line the same way:
Or, if it's a Python 3 script, you should specify
python is almost always Python 2:
However, the problem is that while
/bin/sh is supposed to always exist, and
/bin/bash almost always exists on systems where
bash comes with the OS, Python may exist in a variety of places.
Therefore, many Python programmers use this instead:
#!/usr/bin/env python3 for Python 3.)
This makes the script rely on
env being in the "right place" instead of relying on
python being in the right place. That's a good thing, because:
env is almost always located in
- On most systems, whichever
python should run your script is the one that appears first in the
#!/usr/bin/env python make
/usr/bin/env python hello.py, which is (virtually) equivalent to running
The reason you cannot use
#!python is that:
- You want the interpreter specified to be given by an absolute path (i.e., starting with
- The calling process would execute
python in the current directory. The behavior of searching the path when the command doesn't contain a slash is specific shell behavior.
Occasionally a Python or other script that isn't a shell script will have a shebang line starting with
#!/bin/sh ... where
... is some other code. This is sometimes correct, because there are some ways to invoke the Bourne-compatible shell (
sh) with arguments to make it invoke a Python interpreter. (One of the arguments will probably contain
python.) However, for most purposes,
#!/usr/bin/env python is simpler, more elegant, and more likely to work the way you want.
Shebang Lines in Other Languages
Many programming and scripting languages, and some other file formats, use
# as a comment. For any of them, a file in the language can be run by a program that takes it as an argument by specifying the program on the first line after
In some programming languages,
# is not normally a comment, but as a special case the first line is ignored if it starts with
#!. This facilitates the use of
#! syntax even though
# doesn't otherwise make a line a comment.
Shebang Lines for Files That Don't Run As Scripts
While it's less intuitive, any file whose file format can accommodate a first line starting with
#! followed by the full path of an executable can have a shebang line. If you do this, and the file is marked executable, then you can run it like a program...causing it to be opened like a document.
Some applications use this behavior intentionally. For example, in VMware,
.vmx files define virtual machines. You can "run" a virtual machine as though it were a script because these files are marked executable and have a shebang line causing them to be opened in a VMware utility.
Shebang Lines for Files That Don't Run as Scrips but Act Like Scripts Anyway
rm removes files. It is not a scripting language. However, a file that starts
#!/bin/rm and is marked executable can be run, and when you run it,
rm is invoked on it, deleting it.
This is often conceptualized as "the file deletes itself." But the file is not really running at all. This is more like the situation describe above for
Still, because the
#! line facilitates the running of a simplistic command (including command-line arguments), you can perform some scripting this way. As a simple example of a "script" more sophisticated than
#!/usr/bin/env tee -a
This takes user input interactively, echoes it back to the user line-by-line, and appends it to the end of the "script" file.
Useful? Not very. Conceptually interesting? Totally! Yes. (Somewhat.)
Conceptually Similar Programming/Scripting Concepts (just for fun)