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

tMC*_*tMC 74 python environment-variables

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

env | grep -i python
Run Code Online (Sandbox Code Playgroud)

Gil*_*il' 72

井号线(从“锋利砰”,即#!)由内核处理。内核不想知道诸如PATH. 所以shebang 行上的名称必须是可执行文件的绝对路径。您还可以在脚本名称之前指定一个额外的参数来传递给该可执行文件(这里不涉及系统相关的限制)。例如,对于 Python 脚本,您可以指定

#!/usr/bin/python
Run Code Online (Sandbox Code Playgroud)

在第一行,当你执行脚本时,内核实际上会执行/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
Run Code Online (Sandbox Code Playgroud)

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

虽然这不是官方担保的,历史悠久的Unix系统提供env/usr/bin,与现代系统一直保持正是因为广泛使用的那个位置#!/usr/bin/env。因此,在实践中,指定脚本必须由用户最喜欢的 Python 解释器执行的方法是

#!/usr/bin/env python
Run Code Online (Sandbox Code Playgroud)

  • @NikhilMulley `which` 找到可执行文件并打印其路径。`env` 找到第一个参数指定的程序并执行它,将剩余的参数传递给它。 (10认同)
  • 那么,`env` 本质上是 `which` 的一个 eval 版本。 (4认同)
  • `env` 和 `which` 之间更喜欢哪一个?因为这也将从我的 PATH 环境中获得最符合条件的可执行文件。 (2认同)
  • `which python` 总是产生与 `#!/usr/bin/env python` 相同的结果吗?看来答案是“不”。在这种情况下,我的问题是:我们如何以编程方式确定任何特定 shebang 将执行的内容? (2认同)

jll*_*gre 61

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

#!python
Run Code Online (Sandbox Code Playgroud)

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

#!/usr/local/bin/python
Run Code Online (Sandbox Code Playgroud)

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

使用 env

#!/usr/bin/env python
Run Code Online (Sandbox Code Playgroud)

是一种允许以可移植方式向操作系统指定完整路径的方法,该路径等效于第一个python位于PATH.


小智 9

对,所以运行:

env | grep PATH
Run Code Online (Sandbox Code Playgroud)

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

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

which python
Run Code Online (Sandbox Code Playgroud)