简体   繁体   English

在shebang中使用#!/ usr / bin / env或#!/ bin / env有什么区别?

[英]What's the difference of using #!/usr/bin/env or #!/bin/env in shebang?

会有任何差异,还是个人选择?

#!<interpreter> <arguments> tries to run <interpreter> <arguments> to read and run the rest of the file. #!<interpreter> <arguments>尝试运行<interpreter> <arguments>来读取并运行文件的其余部分。

So #!/usr/bin/env means that there must be a program called /usr/bin/env ; 所以#!/usr/bin/env意味着必须有一个名为/usr/bin/env ;
#!/bin/env means that there must be a program called /bin/env . #!/bin/env表示必须有一个名为/bin/env的程序。

Some systems have one and not the other. 有些系统有一个而另一个没有。

In my experience, most have /usr/bin/env , so #!/usr/bin/env is more common. 根据我的经验,大多数都有/usr/bin/env ,所以#!/usr/bin/env更常见。

Unix systems will try to run <interpreter> using execve , which is why it must be a full path, and #!env without a path will not work. Unix系统将尝试使用execve运行<interpreter> ,这就是它必须是完整路径的原因,并且没有路径的#!env将不起作用。

Mikel explanation is great, it misses just a small fact (which is rather important), it's only one argument being passed including all spaces: 米克尔的解释很棒,它错过了一个小事实(这是非常重要的),它只传递了一个参数,包括所有空格:

#!<Interpreter> <argument>

Results in calling: 调用结果:

$ <Interpreter> '<argument>' path_to_calling_script

So for Example: 所以例如:

$ cat /tmp/test
#!/usr/bin/env python
print "hi"

$ /tmp/test

is the same as calling: 与调用相同:

$ /usr/bin/env "python" /tmp/test

The quotes try to show that if you add any flag or other values will be part of the argument being called. 引号试图表明,如果添加任何标志或其他值将成为被调用的参数的一部分。

 #!/bin/bash -c /bin/env python

Will be interpreted as: 将被解释为:

 $ /bin/bash "-c /bin/env python"

Which won't work. 哪个不行。

/usr/bin/env is a soft link to /bin/env . /usr/bin/env是软链接到/bin/env Essentially, you are using /bin/env 基本上,您正在使用/bin/env

Historically, UNIX had 2 bunches of binaries: 从历史上看,UNIX有两串二进制文件:

  • / filesystem mounted early on boot. / filesystem在启动时提前挂载。
  • /usr might have been mounted later, possibly running scripts and programs from / to arrange the mount. /usr 可能已经被安装后,可能运行脚本和程序/安排安装。 Example: some sites saved space by mounting /usr from network, but you need to get on the network first. 示例:某些站点通过从网络安装/ usr来节省空间,但您需要先进入网络。 Example: it's a large local filesystem, but if it gets damaged, you want tools like fsck to try fixing it. 示例:它是一个大型本地文件系统,但如果它被损坏,您需要像fsck这样的工具来尝试修复它。

Thus, /bin and /sbin (using /lib ), had to contain a minimal system including at least a shell at /bin/sh, scripting essentials like /bin/echo , /bin/test etc., system tools like /bin/mount or /sbin/mount , and /bin/fsck ... 因此, /bin/sbin (使用/lib )必须包含一个最小系统,至少包括/ bin / sh中的shell,脚本必需品,如/bin/echo/bin/test等,系统工具如/bin/mount/sbin/mount ,和/bin/fsck ...

Thus in different unixes, almost any program might have been: 因此,在不同的unix中,几乎任何程序都可能是:

  • in /usr/bin/ but NOT /bin 在/ usr / bin /但是NOT / bin
  • in /bin but NOT /usr/bin 在/ bin但不是/ usr / bin
  • in both, same as symlink 在两者中,与符号链接相同
  • in both but different! 在两个但不同! Eg some systems played with /bin/sh being a very minimal shell (eg dash ) for faster startup, but symlinking /usr/bin/sh -> /usr/bin/bash (iirc, invoking bash as "sh" puts it into some posix mode, but it's still a different more powerful shell). 例如,使用/bin/sh进行的一些系统是一个非常小的shell(例如dash )以便更快启动,但是symlinking /usr/bin/sh - > /usr/bin/bash (iirc,调用bash作为“sh”将它放入一些posix模式,但它仍然是一个不同的更强大的shell)。

Thus the trick of using env to write portable scripts — env just happens to do a PATH lookup. 因此使用env编写可移植脚本的技巧 - env恰好进行了PATH查找。 (It's also useful in other places that don't do PATH lookups, eg docker exec .) (它在其他不进行PATH查找的地方也很有用,例如docker exec 。)

What changed 改变了什么

These were valid use cases but modern Linux followed a similar argument of "need small userspace to mount / recover main userspace" for / itself too! 这些都是有效的使用案例,但现代的Linux也有类似的说法“需要小用户空间来安装/恢复主用户空间”为/本身呢! The pivot syscall and initrd were introduced, and tooling grew to copy the parts you need into it. 引入了pivot syscall和initrd ,并且工具增长以将所需的部件复制到其中。

/usr unification / usr统一

Now, / vs /usr arguably lost its purpose. 现在, / vs /usr可能失去了它的目的。 Having both on one filesystem and symlinking was doable for everybody in principle , though some particular setups would break and would have to change... 原则上对每个人都有一个文件系统和符号链接是可行的,虽然一些特定的设置会破坏并且必须改变...

See https://lwn.net/Articles/483921/ from 2012 for overview of this "/usr unification" idea. 有关此“/ usr统一”构思的概述,请参阅2012年的https://lwn.net/Articles/483921/ For example Fedora completed it: https://fedoraproject.org/wiki/Features/UsrMove . 例如Fedora完成它: https//fedoraproject.org/wiki/Features/UsrMove Many other distros haven't, or are still debating it, or ironing out some kinds to break less users. 许多其他发行版都没有,或者仍然在辩论它,或者为了打破更少的用户而使用某些类型。 For example see debian's preparation: https://wiki.debian.org/UsrMerge . 例如,请参阅debian的准备工作: https//wiki.debian.org/UsrMerge

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM