为什么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 的进程的环境,但我认为内核中当前没有任何东西会访问这样的环境变量。
您可以PATH
使用 -searching 语义env
,因此:
#!/usr/bin/env ruby
Run Code Online (Sandbox Code Playgroud)
具有您想要的语义
#!ruby
Run Code Online (Sandbox Code Playgroud)
依赖PATH
不被认为是好的做法的原因是脚本不能对 PATH 环境变量的内容做任何假设,打破二进制文件的“顺序依赖模型”,其中
/bin
包含启动时所需的可执行文件;/usr/bin
包含操作系统安装使用的其他可执行文件;/usr/local/bin
包含由系统管理员安装的不属于基本操作系统的可执行文件。~/bin
包含用户自己的可执行文件。每个级别不应该假设序列中较晚的二进制文件的存在,它们更“应用”,但可能依赖于更早的二进制文件,它们更“基础”。而 PATH 变量倾向于从应用程序运行到基础,这与上面的自然依赖相反。
为了说明这个问题,问问自己如果一个脚本调用 Ruby 中~/bin
的脚本会发生什么/usr/local/bin
?该脚本应该取决于在 处安装的操作系统版本/usr/bin/ruby
,还是取决于用户碰巧在 处拥有的个人副本~/bin/ruby
? PATH
搜索给出了与后者相关的不可预测的语义(可能~/bin/ruby
是一个断开的符号链接),而在路径中烘焙#!
给出了前者。
真的没有任何其他平台独立的“操作系统......关于注册命令的路径的信息”,所以最简单的事情是坚持在#!
.