shebang 和路径

saw*_*awa 24 scripting path

为什么shebang需要路径?

错误的

#!ruby
Run Code Online (Sandbox Code Playgroud)

正确的

#!/usr/local/bin/ruby

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

操作系统应该有关于注册命令的路径的信息,为什么它仍然期望它被给出?

cjm*_*cjm 22

可能是为了让内核更简单。我不认为内核会搜索您的路径来查找可执行文件。这是由 C 库处理的。 #!处理是在内核中完成的,它不使用标准的 C 库。

另外,我认为内核没有关于您的路径是什么的概念。 $PATH是一个环境变量,只有进程才有环境。内核没有。我想它可以访问执行 exec 的进程的环境,但我认为内核中当前没有任何东西会访问这样的环境变量。


Cha*_*art 6

您可以PATH使用 -searching 语义env,因此:

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

具有您想要的语义

#!ruby
Run Code Online (Sandbox Code Playgroud)

依赖PATH不被认为是好的做法的原因是脚本不能对 PATH 环境变量的内容做任何假设,打破二进制文件的“顺序依赖模型”,其中

  1. /bin 包含启动时所需的可执行文件;
  2. /usr/bin 包含操作系统安装使用的其他可执行文件;
  3. /usr/local/bin 包含由系统管理员安装的不属于基本操作系统的可执行文件。
  4. ~/bin 包含用户自己的可执行文件。

每个级别不应该假设序列中较晚的二进制文件的存在,它们更“应用”,但可能依赖于更早的二进制文件,它们更“基础”。而 PATH 变量倾向于从应用程序运行到基础,这与上面的自然依赖相反。

为了说明这个问题,问问自己如果一个脚本调用 Ruby 中~/bin的脚本会发生什么/usr/local/bin?该脚本应该取决于在 处安装的操作系统版本/usr/bin/ruby,还是取决于用户碰巧在 处拥有的个人副本~/bin/rubyPATH搜索给出了与后者相关的不可预测的语义(可能~/bin/ruby是一个断开的符号链接),而在路径中烘焙#!给出了前者。

真的没有任何其他平台独立的“操作系统......关于注册命令的路径的信息”,所以最简单的事情是坚持在#!.