Why do some python scripts begin with #!/usr/bin/env python? [duplicate]
Solution 1:
Using env in the shebang of a script
Python scripts are not different from scripts in any other language on this.
Either the usage of #!/usr/bin/env python
or #!/usr/bin/python
plays a role if the script is executable, and called without the preceding language. The script then calls the language's interpreter to run the code inside the script, and the shebang is the "guide" to find, in your example, python
.
Using #!/usr/bin/env python
instead of the absolute (full path) #!/usr/bin/python
makes sure python (or any other language's interpreter) is found, in case it might not be in exactly the same location across different Linux- or Unix -like distributions, as explained e.g. here.
Although #!/usr/bin/python
will work on a default Ubuntu system, it is therefore good practice to use #!/usr/bin/env python
instead.
About env
env
is an executable in /usr/bin
, or, as mentioned by @hvd (thanks for the hint!), available as a compatibility symlink in /usr/bin
to env
, in pretty much all Linux distributions.
From Wikipedia:
env is a shell command for Unix and Unix-like operating systems. It is used to either print a list of environment variables or run another utility in an altered environment without having to modify the currently existing environment. Using env, variables may be added or removed, and existing variables may be changed by assigning new values to them.
and in relation to your question:
In practice, env has another common use. It is often used by shell scripts to launch the correct interpreter. In this usage, the environment is typically not changed
More on env
is to be found here, and, as always, in man env
(from a terminal).
Additional information on the shebang; why doesn't #!python work?
In a comment, it was asked why we cannot simply use #!python
as a shebang. Since the interpreter is in $PATH
, the idea is understandable.
The reason is that an executable is executed by execve
, as we can read here. Specifically the lines:
An interpreter script is a text file that has execute permission enabled and whose first line is of the form:
#! interpreter [optional-arg]
The interpreter must be a valid pathname for an executable....
explain that execve
demands a full (valid) path to the interpreter. That makes sense, since scripts (in any language) can e.g. be run at any moment during startup as well, possibly before $PATH
is set at all.
Solution 2:
Jacob's answer explains it well. However there is one more point I would like to mention.
Using /usr/bin/env/
in python serves one more purpose. As python supports virtual environments, using /usr/bin/env python
will make sure that your scripts runs inside the virtual environment, if you are inside one.
Whereas, /usr/bin/python
will run outside the virtual environment.