Should I put #! (shebang) in Python scripts, and what form should it take?
The shebang line in any script determines the script's ability to be executed like a standalone executable without typing python
beforehand in the terminal or when double clicking it in a file manager (when configured properly). It isn't necessary but generally put there so when someone sees the file opened in an editor, they immediately know what they're looking at. However, which shebang line you use is important.
Correct usage for (defaults to version 3.latest) Python 3 scripts is:
#!/usr/bin/env python3
Correct usage for (defaults to version 2.latest) Python 2 scripts is:
#!/usr/bin/env python2
The following should not be used (except for the rare case that you are writing code which is compatible with both Python 2.x and 3.x):
#!/usr/bin/env python
The reason for these recommendations, given in PEP 394, is that python
can refer either to python2
or python3
on different systems.
Also, do not use:
#!/usr/local/bin/python
"python may be installed at /usr/bin/python or /bin/python in those
cases, the above #! will fail."
―"#!/usr/bin/env python" vs "#!/usr/local/bin/python"
Proper shebang for Python script
#!/usr/bin/env python
is more portable because in general the program /usr/bin/env
can be used to "activate" the desired command without full path.
Otherwise, you would have to specify the full path of the Python interpreter, which can vary.
So no matter if the Python interpreter was in /usr/bin/python
or in /usr/local/bin/python
or in your home directory, using #!/usr/bin/env python
will work.
Should I put the shebang line in every python file?
Only files which you will execute by invoking them directly require the shebang. Small hint: if a file contains
if __name__ == "__main__":
main()
it is better (to stick with the Least Astonishment principle) to start it with a shebang. Make sure to have that shebang robust; rather have
#!/usr/bin/env python
than
#!/usr/bin/python
Many module files contain a main
method used to start tests, so many module files start with a shebang.
What shebang should I use to consistently point to python3?
Unfortunately, there is no universally working way of doing this that would work across any and all up front unknown Linux hosts and you are largely left at the mercy of distro maintainers and local host configuration.
alias
won't help, because interpreter specified by #!
handled by the kernel and /usr/bin/env
it will exec in this case does not know about aliases of your shell.
When using env
, you could make sure that the name following env
is first found and means what you want it to mean by:
- making sure all hosts are setup the same way in that respect (expected packaged are installed or at least symlinks are created)
- having user specific construct for execution of your script, such as:
mkdir /tmp/bin
ln -s /usr/bin/python /tmp/bin/python3
PATH="/tmp/bin:${PATH}" ./myscript.py
But none of this is really great and ultimately what you've asked for.
Your interpreter (this is harder than it may sound though, interpreter resolution code is quite simple; where to put it, how to call it for kernel to find and use it) could also be a simple shell script that tries to figure it out that you pack with your python code, but any option you look at isn't really great I am afraid.
There is a PEP-394 for that which suggested / expected on U*X-like system:
- you get
python
for python2 - and
python3
for python3
But it recognizes this has never been entirely consistently applied... and also not as useful in 2020:
However, these recommendations implicitly assumed that Python 2 would always be available. As Python 2 is nearing its end of life in 2020 (PEP 373, PEP 404), distributions are making Python 2 optional or removing it entirely. This means either removing the python command or switching it to invoke Python 3. Some distributors also decided that their users were better served by ignoring the PEP's original recommendations, and provided system administrators with the freedom to configure their systems based on the needs of their particular environment.
TL;DR unfortunately there is no way that universally works and compensates for decisions of various distro and even individual host maintainers. :(
I would most likely opt to stick with #!/usr/bin/env python3
(which has so far been the recommended naming) and add a README
that explains the prerequisites and how to setup the host just to be sure.
For the sake of completeness I should add, the PEP does make a recommendation in this regard: setup and use virtual environment or use a (third party) environment manager. However the way I read the question: "Portable interpreter specification that does not make any assumptions about nor poses any (additional) requirements to target host configuration", this would then not fit the bill and would not mean a substantial improvement over saying: make sure you have python3
executable in the search path and create a symlink if not.
Python - what is the shebang line supposed to do if the stated version is not installed ?? what if shebang is not the first line?
The shebang is what will be run if the script is run with chmod +x test.py
and then ./test.py
. Then the shell (i.e. bash) will run /usr/bin/env python2 test.py
. However, when you explicitly use python3 test.py
the shell will not check your shebang, it will just run python3
.
Also, if you put the shebang at any line other than the first, it is no longer a shebang. Quoting Wikipedia:
In computing, a shebang is the character sequence consisting of the characters number sign and exclamation mark (#!) at the beginning of a script.
The shsebang can only be at the biginning. If it is not then the shell will not look at it, so it ran test.py
as a shell script, where many commands are not found.
Purpose of #!/usr/bin/python3 shebang
#!/usr/bin/python3
is a shebang line.
A shebang line defines where the interpreter is located. In this case, the python3
interpreter is located in /usr/bin/python3
. A shebang line could also be a bash
, ruby
, perl
or any other scripting languages' interpreter, for example: #!/bin/bash
.
Without the shebang line, the operating system does not know it's a python script, even if you set the execution flag (chmod +x script.py
) on the script and run it like ./script.py
. To make the script run by default in python3, either invoke it as python3 script.py
or set the shebang line.
You can use #!/usr/bin/env python3
for portability across different systems in case they have the language interpreter installed in different locations.
Proper shebang of python script running on Windows
The interpretation of the shebang lines on Linux (and Unix like machines) is done by the operating system, and Windows doesn't do that, so there is no proper shebang line.
So if you don't want to do something special like selecting a particular Python version for your program, you can leave out the shebang (or leave in the one you need for running on Linux).
If your .py
files are registered on Windows to be started by a particular Python executable, it is possible to check the first line of that file and interpret it to make sure you start the right version.
It is possible to start another Python version in that way with the original file and other arguments, but keep in mind that if you use that to start e.g a Python 2.7 interpreter where Python 3.8 is the one registered, that your Python program must be valid Python for both versions (so no print
statements, f'{somevar}'
strings, etc.)
Related Topics
Open Web in New Tab Selenium + Python
How to Print a Number Using Commas as Thousands Separators
Converting Unix Timestamp String to Readable Date
How to Change the Order of Dataframe Columns
How to Prettyprint a Json File
When Is "I += X" Different from "I = I + X" in Python
How to Compare Two Lists in Python and Return Matches
Python Subprocess Readlines() Hangs
Equivalent to Time.Sleep For a Pyqt Application
How to Stop More Than 1 Bullet Firing At Once
How to Melt a Pandas Dataframe
How to Find the Duplicates in a List and Create Another List With Them
Return, Return None, and No Return At All
String Comparison in Python: Is Vs. ==
How Can the Euclidean Distance Be Calculated With Numpy
Process Escape Sequences in a String in Python