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...
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It only takes a minute to sign up.
Sign up to join this communityPython 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:
.
In the case of Python files, this is typically .py
..py
files should be opened using the newly-installed application Python (i.e. the Python interpreter)..exe
, and .bat
files are executed as Windows batch-scripts..py
files using python.exe
, it should open them with some other program, such as the text editor notepad.exe
.
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:
.py
at the end in order to have them automatically recognized as such..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:
#!
, 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.This has a couple of advantages:
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>
.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.
/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).
/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
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.
#!/bin/bash -x
, #!/usr/bin/perl -lan
, etc).
/usr/bin/env python
to get the correct python.
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.
./
. 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
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
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
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
hashbang
(#
= "hash") or shebang
(#
= "sharp"), depending on how you name the #
character. However, shebang
is indeed more common. @KyleStrand
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
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.
to run Python codes in an executable script i.e. defines how the codes should be run and using what interpreter;
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
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.
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.
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.
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.
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.
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.
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.
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.
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.
.
) 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.python myscript.py
instead.