/ usr / bin / env如何知道要使用哪个程序?


62

当我使用shebang #!/usr/bin/env python运行脚本时,系统如何知道python要使用哪个脚本?如果我python在环境变量中查找bin路径,我什么也找不到。

env | grep -i python

6
哦,我想我想通了-它只是在$ PATH中搜索“ python”
tMC 2011年

我也想知道。为什么是/ usr / bin / env?与/ bin / env或env相反,如果它只是从env获取路径列表?
Faheem Mitha

只是'env'是行不通的,因为它必须是完整路径。“ env”程序通常位于/ user / bin / env中。在某些发行版中,它也可能是/ bin / env,但使用/ usr / bin / env更安全。
2011年

Answers:


54

shebang期望使用解释器的完整路径,因此以下语法将不正确:

#!python

设置像这样的完整路径可能有效:

#!/usr/local/bin/python

但将非便携的蟒蛇可能安装/bin/opt/python/bin或者是任何其他位置。

使用 env

#!/usr/bin/env python

是一种方法,允许通过便携式方式向操作系统指定一条完整路径,该路径等同于python最初位于PATH


56

井号线(从“锋利砰”,即#!)由内核处理。内核不想知道环境变量,例如PATH。因此,shebang行上的名称必须是可执行文件的绝对路径。您还可以在脚本名称之前指定一个附加参数,以传递给该可执行文件(具有与系统相关的限制,我在这里不再赘述)。例如,对于Python脚本,您可以指定

#!/usr/bin/python

在第一行,执行脚本时,内核实际上将执行/usr/bin/python /path/to/script。但这并不方便:您需要指定命令的完整路径。如果您有什么python/usr/bin某些机器上和/usr/local/bin别人?或者你可以设置你PATH/home/joe/opt/python-2.5/bin这样使用Python的特定版本?由于内核不会PATH为您执行查找,因此,其想法是使内核运行一个命令,该命令依次在中查找所需的解释器PATH

#!/fixed/path/to/path-lookup-command python

path-lookup-command必须以可执行文件的名称作为参数,并在其中查找PATH并执行它:内核将运行/fixed/path/to/path-lookup-command python /path/to/script。碰巧的是,env命令就是这样做的。它的主要目的是在不同的环境下运行命令,但是由于它在中查找命令名称$PATH,因此非常适合我们的目的。

尽管没有正式保证,但是提供env了历史悠久的Unix系统/usr/bin,而现代系统正是由于广泛使用,所以保留了该位置#!/usr/bin/env。因此,实际上,指定脚本必须由用户喜欢的Python解释器执行的方法是

#!/usr/bin/env python

2
env和之间最好选择哪一个which?因为这还将从我的PATH环境中获取最合格的可执行文件。
Nikhil Mulley,2012年

8
@NikhilMulley which找到可执行文件并打印其路径。env查找第一个参数指定的程序并执行,然后将其余参数传递给它。
凯文(Kevin)

3
envwhich本质上的评估版本。
Nikhil Mulley '02

6

对,所以运行:

env | grep PATH

您的$ PATH是目录列表。Unix将按顺序遍历该目录列表,直到找到“ python”为止。

您可以使用“哪个”命令查看找到的目录:

which python

有趣的是,我看到sys.path激活的env $ env python3['', '/home/user/test', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/home/user/.local/lib/python3.4/site-packages', '/usr/lib/python3.4/site-packages', '/usr/local/lib/python3.4/dist-packages', '/usr/lib/python3/dist-packages'])和./env/bin/python3 (['', '/home/user/test', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/home/user/test/env3/lib/python3.4/site-packages'])之间的python有所不同。
ThorSummoner
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.