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.