Python Scripts in Linux – Why Use #!/usr/bin/python

pythonscripts

Pretty simple question: In Linux, why does Python require the line

#!/usr/bin/python

at the start of a python file, since Windows doesn't?

What does it do? 'cause the description "Links to Python" is a bit vague…

Best Answer

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>
Related Question