Mik*_*kel 14
#!<interpreter> <arguments>尝试运行<interpreter> <arguments>以读取并运行文件的其余部分.
所以#!/usr/bin/env意味着必须有一个叫做的程序/usr/bin/env;
#!/bin/env意味着必须有一个名为的程序/bin/env.
有些系统有一个而另一个没有.
根据我的经验,大多数人都有/usr/bin/env,所以#!/usr/bin/env更常见.
Unix系统将尝试<interpreter>使用execve,这就是为什么它必须是一个完整的路径,#!env没有路径将无法工作.
/文件系统在启动时早期安装。/usr 可能稍后安装,可能运行脚本和程序来/安排安装。示例:有些站点通过从网络挂载 /usr 来节省空间,但您需要先连接网络。示例:它是一个大型本地文件系统,但如果它被损坏,您需要诸如fsck尝试修复它之类的工具。因此,/bin并且/sbin(使用/lib)必须包含一个最小的系统,其中至少包括位于 /bin/sh 的 shell、脚本必需品(例如/bin/echo等/bin/test)、系统工具(例如/bin/mount或/sbin/mount)、以及/sbin/fsck...
因此,在不同的 UNIX 中,几乎所有程序都可能是:
\n/bin/sh一个非常小的 shell(例如dash)来加快启动速度,但符号链接/usr/bin/sh-> /usr/bin/bash(iirc,调用 bash 作为“sh”将其置于某种 posix 模式,但它仍然是一个不同的更强大的 shell)。大多数时候,只需设置 $PATH 来包含这两个区域。但某些上下文喜欢#!或docker exec需要固定的完整路径。env因此,使用编写可移植脚本 \xe2\x80\x94的技巧env恰好是进行 PATH 查找。
这些都是有效的用例,但现代 Linux 本身也遵循类似的“需要小用户空间来安装/恢复主用户空间”的论点/! 引入了pivot 系统调用initrd,并且工具不断发展以将您需要的部分复制到其中。
现在,/VS/usr可以说失去了它的目的。原则上,在一个文件系统上同时使用符号链接对每个人来说都是可行的,尽管某些特定的设置会被破坏并且必须更改......
有关“/usr 统一”想法的概述,请参阅2012 年的https://lwn.net/Articles/483921/ 。例如 Fedora 完成了它: https: //fedoraproject.org/wiki/Features/UsrMove。许多其他发行版还没有,或者仍在争论,或者解决某些问题以减少用户流失。例如,请参阅 debian 的准备工作:https://wiki.debian.org/UsrMerge。
\n需要 PATH 查找的原因还有很多:
\nenv总是存在于 /bin 或 /usr/bin 或两者中,但人们可能只在 /usr/local 或您的主目录下有(或更喜欢)python 和其他解释器...#!/usr/bin/env python3,那么您只需使用特定于该环境的模块即可。env自己使用什么完整路径?按照同样的逻辑,在具有不同 /usr 的系统中,env其本身可能从任一位置丢失,因此您无法编写 100.00% 可移植的#!行。
\n实际上,两者都可能有效。我没有统计数据,但在多年的实践中,我认为/usr/bin/env这是更常用的推荐形式(示例)