62

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

12
  • 30
    The answers below are all correct, none of them address why Windows does not need this line. Windows depends upon the extension of the file (the part after the .) to determine what kind of file it is. Even Windows is moving away from this: examine the first few lines of the Microsoft Word file, and it will state that it is in fact, a Microsoft Word file. Nov 4, 2015 at 22:16
  • 10
    The elephant in the room is that you should NEVER use /usr/bin/python unless you are compatible with python 2 and 3. Reason: arch symlinks it to python3, a move which is acknowledged by the PSF, who recommend against it themselves. Nov 5, 2015 at 3:50
  • 10
    It's implied, but not stated explicitly in the answers below that it's not required. It's required if you want to execute the script just from ts own name. You can always run python myscript.py instead.
    – Chris H
    Nov 5, 2015 at 10:32
  • 3
    @CharlesGreen we are not suppose to know why windows does not ;-) That is up to SO.
    – Rinzwind
    Nov 5, 2015 at 13:13
  • 2
    @YetAnotherUser It's been six years and eleven months since Python 3 was released, at this point I feel people would be better off defaulting to 3 and explicitly specifying the use of 2 when necessary.
    – JAB
    Nov 5, 2015 at 15:56

8 Answers 8

76
+50

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>
8
  • 1
    On Windows you could easily have .py2 and .py3 extensions for Python 2 / Python 3 scripts. So both Linux (+x bit) and Windows (file extension) need metadata in the filesystem. The main difference is that the +x bit is more easily lost in transit. This is not necessarily a downside.
    – MSalters
    Nov 6, 2015 at 13:17
  • 1
    @MSalters The execute bit also has a lot less information encoded in it. And note that you might have multiple Python2 interpreters on a given system (there was a similar situation with Ruby and other languages at a previous job of mine); dealing with this via the shebang line is nearly trivial, whereas the situation on Windows gets substantially less tractable the more you attempt to manage multiple similar file-types. Nov 6, 2015 at 17:41
  • Also, does the extension really count as "metadata"? It's just part of the filename. Nov 6, 2015 at 17:42
  • 3
    The metadata of a file includes the whole filename, creation time, access bits, etc. Only the content itself is data instead of metadata. As for the "multiple interpreters", that is indeed a real problem and exactly why it shouldn't be in the shebang line. What if you have /usr/bin/i686/python and /usr/bin/amd64/python ? Perfectly reasonable, but it breaks python scripts that have a hardcoded assumption on /usr/bin/python. The choice of interpreter is not a choice of the script writer but of the script user, The script writer only gets to choose the language (dialect).
    – MSalters
    Nov 6, 2015 at 17:52
  • 1
    @MSalters Well, that's what /usr/bin/env, is for, along with env-setup scripts. What's the Windows version of this? Running a regedit script right before you launch a .py file to ensure that you get the interpreter you want? Nov 6, 2015 at 18:06
43

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.

6
  • 1
    An interesting thing to add would be that it's possible to specify additional parameters after the shebang itself, in most of the cases in the same way as if the interpreter was called directly (#!/bin/bash -x, #!/usr/bin/perl -lan, etc).
    – kos
    Nov 5, 2015 at 3:47
  • 7
    @kos: I think you can specify exactly one extra argument, which has been a PITA when one (should) use /usr/bin/env python to get the correct python.
    – mike3996
    Nov 5, 2015 at 8:50
  • @progo Not sure what the problem with env is, but the problem seems to not be the number of arguments: #!/usr/bin/perl -l -a -n has three arguments but it works. Though again, I'm not able to grok the exact problem.
    – kos
    Nov 5, 2015 at 10:28
  • When explicitly calling an interpreter with the script as argument, there is no reason to have the latter start with ./. In other words just python filename.py or bash script.sh will work fine. The only reason to include ./ is in a command name, when you want to tell the shell not to search in $PATH (which probably wont find files in the current directory) but take the path you specified as-is. But that does not apply to command arguments. Nov 5, 2015 at 10:55
  • @kos: The problem could be in how env receives the rest of the arguments from kernel. They could all be presumed to be one large argument with no splitting-by-space performed. Sorry for articulation, I don't remember the details of this that well anymore
    – mike3996
    Nov 5, 2015 at 12:35
17

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
2
  • 2
    I don't think I've ever seen a hyphen in shebang. Since the word is formed from "hash" and "bang," your spelling is not very clear, since it looks like it's a combination of "she" and "bang". Nov 5, 2015 at 21:52
  • You can call it hashbang (# = "hash") or shebang (# = "sharp"), depending on how you name the # character. However, shebang is indeed more common. @KyleStrand
    – Byte Commander
    Dec 14, 2015 at 16:15
7

Technically, it doesn't require it. It requires a path to the environment where your script executes. Your future scripts would be better off to include /usr/bin/env then, specify python. This grantees that your script runs in the python environment no matter where python is installed. You want to do this for compatibility reasons, you cannot be sure the next person you share your code with will have python installed in usr/bin/python, or that they will have permissions to those system files.

Here is a similar Q&A from stack overflow.

What that looks like in your script is:

#!/usr/bin/env python

I also see some concern for how to specify python3. Here is how to do it:

#!/usr/bin/env python3
5

In Linux, Python may or may not require the #! (shebang) line. This depends on how the Python codes are handled, either running the codes in Python interactive mode or in a Python script.

Python interactive mode allows the user to type and run Python codes directly, which does not require the shebang line. To run the interactive mode, open a Terminal and type python for Python 2.X or python3 for Python 3.X.

$  python
Python 2.7.6 (default, Jun 22 2015, 18:00:18) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 

$  python3
Python 3.4.3 (default, Oct 14 2015, 20:33:09) 
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

Python script allows the user to write and save the Python codes in a plain text file, then run the codes later. This may or may not require the shebang line. However, there are two known reasons when the shebang line is required for using Python script in Linux.

  1. to run Python codes in an executable script i.e. defines how the codes should be run and using what interpreter;

  2. to run Python codes with respect to specific version of Python i.e. run codes that are compatible with either Python 2.X or Python 3.X only

Practice with Python scripts

Below are the list and content of files, which I have used to show cases that #! (shebang) line is required or not required.

$  ls -ln *.py
-rw-rw-r-- 1 1000 1000  94 Dec 14 18:37 hello1.py
-rwxrwxr-x 1 1000 1000 116 Dec 14 18:37 hello2e.py
-rw-rw-r-- 1 1000 1000 116 Dec 14 18:37 hello2.py
-rwxrwxr-x 1 1000 1000 117 Dec 14 18:37 hello3e.py
-rwxrwxr-x 1 1000 1000 120 Dec 14 18:37 hello3m.py
-rw-rw-r-- 1 1000 1000 117 Dec 14 18:37 hello3.py

$  file *.py
hello1.py:  ASCII text
hello2e.py: Python script, ASCII text executable
hello2.py:  Python script, ASCII text executable
hello3e.py: Python script, ASCII text executable
hello3m.py: Python script, UTF-8 Unicode (with BOM) text executable
hello3.py:  Python script, ASCII text executable
  • hello1.py contains source code only.

    import sys
    sys.stdout.write("Hello from Python %s\n" % (sys.version,))
    print("Hello, World!")
    
  • hello2.py contains source code and the shebang line.

    #!/usr/bin/env python
    import sys
    sys.stdout.write("Hello from Python %s\n" % (sys.version,))
    print("Hello, World!")
    
  • hello2e.py contains same as hello2.py and made executable.

  • hello3.py contains same as hello2.py, except it is adapted to run with Python 3 by renaming the first line to #!/usr/bin/env python3.

  • hello3e.py contains same as hello3.py and made executable.

  • hello3m.py contains same as hello3.py and made executable, except saved with Write Unicode BOM option in the text editor i.e. Mousepad.

Beyond this point, user will be presented with two methods to run the Python scripts. Both methods have been demonstrated as below.

Method 1: Run with Python program

Below are the commands and output when running the source code with Python 2 and Python 3.

$  python hello1.py
Hello from Python 2.7.6 (default, Jun 22 2015, 18:00:18) 
[GCC 4.8.2]
Hello, World!

$  python3 hello1.py
Hello from Python 3.4.3 (default, Oct 14 2015, 20:33:09) 
[GCC 4.8.4]
Hello, World!

Both versions of Python were able to run the script successfully. Hence, the shebang line is not required when running the Python script via python or python3 command.

Method 2: Run as Python script

Below are the commands and output when running the source code with the shebang line, which are adapted to neither, Python 2 and Python 3, including non-executable and executable cases.

$  ./hello1.py
bash: ./hello1.py: Permission denied

$  ./hello2.py
bash: ./hello2.py: Permission denied

$  ./hello3.py
bash: ./hello3.py: Permission denied

$  ./hello2e.py 
Hello from Python 2.7.6 (default, Jun 22 2015, 18:00:18) 
[GCC 4.8.2]
Hello, World!

$  ./hello3e.py 
Hello from Python 3.4.3 (default, Oct 14 2015, 20:33:09) 
[GCC 4.8.4]
Hello, World!

The first three scripts have failed because these scripts are non-executable, regardless of having the shebang line or not (For supporting proof, see Additional example below). The last two scripts have shebang line and are executable.

Apparently, a script that has been made executable is essentially useless without the shebang line. Hence, the shebang line is required and the script must be executable when running the Python codes in an executable script.

When shebang does not work

In my prepared and tested example, running hello3m.py as an executable script has failed and returned an error.

$  ./hello3m.py 
./hello3m.py: line 1: #!/usr/bin/env: No such file or directory

This is a known limitation that shebang does not work or becomes invalid. When a file is saved as Unicode BOM (Byte Order Mark), it will fail to run normally as an executable Python script.

Additional example

This additional example shall be treated as supporting proof only. User should avoid running this example, although the result is harmless.

I have created another file called hello1e.py, which contains same as hello1.py and made executable. Running this script returned a syntax error.

$  ./hello1e.py 
./hello1e.py: line 2: syntax error near unexpected token `"Hello from Python %s\n"'
./hello1e.py: line 2: `sys.stdout.write("Hello from Python %s\n" % (sys.version,))'

When running this script, at first, the mouse cursor will be changed to a plus-sign and does nothing in appearance. The syntax error will not be shown until I made a click on the Desktop or Terminal window. Then, this script will create a sys file in the same directory as the script.

$  file sys
sys: PostScript document text conforming DSC level 3.0, Level 1

The sys file has been identified as PostScript file, without file extension. This file can be opened in document viewer i.e. Evince, and the file actually contained a screenshot of the window that I had clicked earlier. In my experience, the file can be as large as few Megabytes.

Once again, the shebang line is required and the script must be executable when running the Python script as an executable script. Otherwise, the script will misbehave as described above.

Additional notes

The term "made executable" or "must be executable" refers to the permission to run the script. This is done by running chmod +x FILENAME command in Terminal, or by checking the option "Allow this file to run as a program" or something similar in the Properties window, within a file manager.

While other existing answers had covered almost everything, this answer has taken different approach by using practical examples to explain the matter. The code syntax have been written with care, such that the examples could be run with either Python 2 or Python 3, as it is.

The Python codes have been adapted from Using Python on Windows and Using Python on Unix platforms, with additional one-line code of the ubiquitous "Hello, World!" program.

All codes and commands have been fully tested and works in Xubuntu 14.04 system, which had Python 2.7 and Python 3.4 installed by default.

4

It means that when that file is executed your computer knows to execute it with the program /usr/bin/python, that's how you tell it apart from another language, such as bash where you would do #!/bin/bash. This is so that you can simply run:

./[file-to-execute]

And it will know which file to execute it with, rather than you yourself having to specify with something like:

python ./[file-to-execute].py

The #! part is commonly refereed to as a shebang, crunch bang or hashbang.

1
  • 2
    Also a hashbang. Nov 5, 2015 at 0:37
1

If you have several versions of Python installed, /usr/bin/env will ensure the interpreter used is the first one on your environment's $PATH. The alternative would be to hardcode something like #!/usr/bin/python;

In Unix, an executable file that's meant to be interpreted can indicate what interpreter to use by having a #! at the start of the first line, followed by the interpreter (and any flags it may need).

This rule only applicable for UNIX based system.

0

Helpful for OS's like Linux where Python 2.x is still the standard, but most people also download 3.x.

2.x would run by default. So my 3.x code, I prefix with

#!/usr/bin/env python3

so that 3.x runs the code. I can even specify down to the minor revision (python 3.x.y.z) if I so chose to have beta releases or just slightly older versions.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .