会有任何差异,还是个人选择?
答案 0 :(得分: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
将无效。
答案 1 :(得分:2)
米克尔的解释很棒,它错过了一个小事实(这很重要),它只传递了一个包含所有空格的参数:
#!<Interpreter> <argument>
调用结果:
$ <Interpreter> '<argument>' path_to_calling_script
所以例如:
$ cat /tmp/test
#!/usr/bin/env python
print "hi"
$ /tmp/test
与调用相同:
$ /usr/bin/env "python" /tmp/test
引号试图表明如果添加任何标志或其他值将成为被调用参数的一部分。
#!/bin/bash -c /bin/env python
将被解释为:
$ /bin/bash "-c /bin/env python"
哪个不起作用。
答案 2 :(得分:1)
/usr/bin/env
是指向/bin/env
的软链接。基本上,您使用的是/bin/env
答案 3 :(得分:0)
/
文件系统在启动初期安装。/usr
可能已在以后挂载,可能正在运行/
中的脚本和程序来安排挂载。示例:某些站点通过从网络挂载/ usr来节省空间,但是您需要首先进入网络。例如:这是一个很大的本地文件系统,但是如果它受到损坏,则需要fsck
之类的工具来尝试对其进行修复。因此/bin
和/sbin
(使用/lib
)必须包含一个最小系统,该系统至少应包括/ bin / sh处的shell,并且必须编写类似/bin/echo
的脚本,/bin/test
等系统工具,例如/bin/mount
或/sbin/mount
和/bin/fsck
...
因此在不同的unix中,几乎所有程序都可能是:
/bin/sh
作为最小的外壳程序(例如dash
)来加快启动速度,但是将/usr/bin/sh
-> /usr/bin/bash
进行符号链接(iirc,以“ sh”的形式调用bash进入posix模式,但仍然是另一个功能更强大的shell)。因此,使用env
编写可移植脚本的技巧-env
恰好进行了PATH查找。 (它在其他不进行PATH查找的地方也很有用,例如docker exec
。)
这些是有效的用例,但是现代Linux也为/
本身遵循类似的论点“需要小的用户空间来装载/恢复主用户空间”! The pivot syscall and initrd
被引入,并且工具不断发展,可以将您需要的部分复制到其中。
现在,/
与/usr
可能失去了目标。原则上,每个人都可以同时使用一个文件系统和符号链接,尽管某些特定的设置可能会中断并且必须更改...
有关“ / usr统一”思想的概述,请参见2012年的https://lwn.net/Articles/483921/。例如Fedora完成了它:https://fedoraproject.org/wiki/Features/UsrMove。许多其他发行版都没有,或者仍在辩论中,或者正在淘汰某些发行版以减少用户数量。例如,请参见debian的准备工作:https://wiki.debian.org/UsrMerge。