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,
#!/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.
#!/usr/bin/python will work on a default Ubuntu system, it is therefore good practice to use
#!/usr/bin/env python instead.
env is an executable in
/usr/bin, or, as mentioned by @hvd (thanks for the hint!), available as a compatibility symlink in
env, in pretty much all Linux distributions.
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
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....
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.