Why does Python in Linux require the line #!/usr/bin/python?

Python does not have any such special requirement on Linux. It's the program loader on Unix/Linux that uses the "shebang" line, as it's called. This is actually a feature rather than a limitation, but we'll get to that in a moment. The Wiki page on "shebang" has more details, but I'll try to give an overview as well as a comparison to Windows here.

First, let's look at the situation on Windows:

  • When you attempt to open or run a file, Windows first examines the extension of that file. This is the last part of the filename starting with . In the case of Python files, this is typically .py.
  • Windows looks up what action to take based on the file extension.
    • This information is recorded in the Windows registry; when Python is installed, it typically tells Windows that .py files should be opened using the newly-installed application Python (i.e. the Python interpreter).
    • Several file-types have built-in behaviors; for instance, executable files (such as the Python interpreter itself) must end in .exe, and .bat files are executed as Windows batch-scripts.
    • The action taken for a particular file-type is customizable. You can, for instance, tell Windows that instead of running .py files using python.exe, it should open them with some other program, such as the text editor notepad.exe.
      • In this case, in order to run a Python script, you would need to manually call python <scriptname>.py (or write a .bat file to do this for you).

Now, what happens if there's a shebang line (#!/usr/bin/python or #!/usr/bin/env python) at the top of the Python script? Well, since # is a comment line in Python, the Python interpreter just ignores it. This is one reason why most scripting languages used in the Unix/Linux world use # to start comment lines.

So it's a bit misleading to say that Windows "doesn't need" the #! line; Windows doesn't see the #! line, and in fact relies on the file-extension to tell it what to do. This has a couple of disadvantages:

  • You must name Python scripts with .py at the end in order to have them automatically recognized as such.
  • There's no easy way to distinguish Python2 scripts from Python3 scripts.
  • As previously noted, if you change the default launch behavior for the .py file-type, Windows will no longer automatically run those scripts with Python. Note that this could be done unintentionally.

Now, let's look at how Unix/Linux launches scripts:

The first thing to note is that Unix/Linux, unlike Windows, isn't trying to "open" Python scripts using a particular program, at least conceptually; the OS knows that the script is something that can be executed because of something called the "execute bit" (which is outside the scope of this answer). So, if you accidentally type #!/usr/bin/pthon instead of #!/usr/bin/python, you'll get an error message that includes this text:

/usr/bin/pthon: bad interpreter: No such file or directory.

The word "interpreter" gives us a clue about the role of the shebang line (though technically the specified program can be something other than an interpreter, such as cat or a text editor). When you attempt to execute a file, here's what happens:

  • The Unix/Linux program loader looks at the first two bytes of that file; if these two bytes are #!, then the loader interprets the remainder of the shebang line (excluding the shebang itself) as a command to launch an interpreter with which to run the file contents as a script.
  • The program loader launches the specified interpreter, feeding it the path of the original file as an argument.

This has a couple of advantages:

  • The script-writer has more control over which interpreter will be used (which solves the Python2/Python3 issue) and can sometimes pass an extra argument to the interpreter (see the Wiki page for details).
  • The filename of the script is ignored, so you can name Python scripts whatever you want.

Note, finally, that Unix/Linux does not need the shebang line in order to run a Python script. Recall that all the shebang line actually does is allow the program loader to select an interpreter. But just as in Windows, this can be done manually:

python <myscript>

The line you've indicated is used to tell the computer what program / interpreter to use when running the file/script directly, and any arguments that should be passed to that program when the script runs. This is not, however, a requirement of Python, it's a requirement of the linux kernel/system if you intend to run the script directly (and not pass it to Python by the below syntax).

It is not needed if you are going to execute python script.py or similar. It is only needed if you intend to run the script/file directly, without also providing the interpreter to use (such as python).


For a Bash script, it would have something like this:

#!/bin/bash [optional Bash arguments]
# Bash script code here
...
exit 0;

This would indicate to the system that, when this runs, it should be run via /bin/bash which is one of the shells / shell-script languages on the system.


For Python code, though, here, you're going to be wanting to have the executable file run via Python, so you tell it what interpreter you intend to have run in it.

#!/usr/bin/python [optional Python arguments]
# Python code here
...
exit()

This, like for Bash, indicates that /usr/bin/python should be used (this is likely Python 2 or Python 3, depending on your individual system configurations).


In this way, you can run ./filename.py or ./executable or ./scripttorun directly.

Without that line at the beginning, and assuming you have set the file/script to be executable, and assuming you're working with a Python script, you would have to run python filename.py or similar if you did not have the #!/usr/bin/python line. (For a Bash script, you would have to do bash script.sh, or similar for other scripts/languages, such as Perl, Ruby, etc.)

Syntax highlighting above is language-specific in each section, although it doesn't really matter.


The line:

#!/usr/bin/python

is called the 'shebang' and it indicates the path to the interpreter binary that will be used to interpret the rest of the commands in the file. It is usually the first line of a script.

So the line #!/usr/bin/python indicates that the content of the file will be interpreted by the python binary located at /usr/bin/python.

Note that the shebang line is parsed by the kernel and then the script will eventually be called as an argument:

python script_name

Similarly in case of #!/bin/bash:

bash script_name

Tags:

Python

Scripts