63

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

Seth
  • 59,332
TellMeWhy
  • 17,964
  • 41
  • 100
  • 142

8 Answers8

76

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

Thomas Ward
  • 78,878
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
z3ntu
  • 75
heemayl
  • 93,925
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
j0h
  • 15,365
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

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.

Martin Thoma
  • 20,535
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.

orvi
  • 363
  • 2
  • 11