为什么不使用无路径shebang?

Ame*_*ina 26 shell shebang

是否有可能有一个shebang,而不是指定解释器的路径,而是具有解释器的名称,并让shell通过$PATH找到它?

如果没有,有什么原因吗?

Gil*_*il' 23

PATH 查找是用户空间中标准 C 库的一项功能,一般环境变量也是如此。内核不会看到环境变量,除非它从调用者传递execve到新进程的环境。

内核不对中的路径执行任何解释execve(这取决于包装函数,例如execvp执行 PATH 查找)或 shebang(或多或少在execve内部重新路由调用)。所以你需要把绝对路径放在shebang¹中。在最初的家当实施只是的几行代码,到现在也没有得到显著因为扩大。

在 Unix 的第一个版本中,当 shell 注意到您正在调用一个脚本时,它会执行调用自身的工作。出于多种原因将 Shebang 添加到内核中(总结Dennis Ritchie基本原理

  • 调用者不必担心要执行的程序是 shell 脚本还是本机二进制文件。
  • 脚本本身指定要使用的解释器,而不是调用者。
  • 内核使用日志中的脚本名称。

无路径 shebangs 需要增加内核以访问环境变量和进程PATH,或者让内核执行执行 PATH 查找的用户空间程序。第一种方法需要向内核添加不成比例的复杂性。第二种方法已经可以使用#!/usr/bin/envshebang 了

¹如果您输入相对路径,它会相对于进程的当前目录(而不是包含脚本的目录)进行解释,这在 shebang 中几乎没有用。

  • 对于那些对“shebang 如何在内部重新路由 execve 调用”感到好奇的人:它实际上是在需要它们的可执行文件上运行解释器的通用机制的一部分。动态链接的 ELF 可执行文件由 `/lib64/ld-linux-x86-64.so.2`(参见 `ldd` 输出)“解释”。Linux 使其完全通用:`binfmt` 支持(自 2.1.43 起)允许您注册解释器路径/幻数或文件扩展对。您可以在运行时让 PE32 `.exe` 调用 `wine`,Java 类和 jar 文件调用 `java` 等。 (5认同)
  • 不,内核不需要在 `execve` 和 shebang 中的绝对路径,尽管在 shebang 中具有相对路径没有什么意义。 (2认同)

Bru*_*ger 19

发生的事情比我们看到的还要多。#!由 Unix 或 Linux 内核解释的行#!不是 shell 的一个方面。这意味着PATH在内核决定执行什么时并不真正存在。

处理不知道要运行哪个可执行文件或以perl可移植方式或类似方式调用的最常见方法是使用#!/usr/bin/env perl. 内核执行/usr/bin/env,它继承了一个PATH环境变量。env寻找(在这个例子中)perlPATH,并使用execve(2)系统调用来获得内核运行的perl可执行文件。