Answers:
您可以PATH
使用来搜索语义env
,因此:
#!/usr/bin/env ruby
具有您想要的语义
#!ruby
视之为PATH
最佳做法的原因是该脚本无法对PATH环境变量的内容进行任何假设,从而破坏了二进制文件的“顺序依赖模型”,其中
/bin
包含启动时所需的可执行文件;/usr/bin
包含操作系统安装所使用的其他可执行文件;/usr/local/bin
包含系统管理员安装的不属于基本操作系统的可执行文件。~/bin
包含用户自己的可执行文件。每个级别都不应该假设序列中后面的二进制文件存在,这些二进制文件更“应用”,而可能更早地依赖二进制文件,这些二进制文件更“基础”。PATH变量倾向于从应用到基本,这与上面的自然依赖相反。
为了说明问题,请问自己一个问题,如果脚本中~/bin
的脚本/usr/local/bin
调用Ruby中的脚本,会发生什么?该脚本是否应该取决于OS的安装版本/usr/bin/ruby
,或者取决于用户恰巧拥有的个人副本~/bin/ruby
? PATH
搜索给出了与后者相关的不可预测的语义(可能~/bin/ruby
是断开的符号链接),同时烘烤了#!
给出后者的路径。
实际上并没有任何其他与平台无关的“操作系统...有关已注册命令路径的信息”,因此最简单的方法是坚持使用中提供的路径#!
。
Shell脚本通常以开头
#! /bin/sh
。如果您/bin/sh
不符合POSIX,请使用指向POSIX兼容的shell的路径。还有一些底层的“陷阱”需要注意:
- 您必须知道要运行的解释器的完整路径名。这可以防止跨供应商的可移植性,因为不同的供应商将事物放置在不同的位置(例如
/bin/awk
vs/usr/bin/awk
)。
还有其他原因,但是从安全角度来看,我永远不会希望脚本对正确的路径进行假设。如果错了,并且运行了错误的shell或解释器怎么办?被恶意用户插入的一个?或者,如果它依赖于特定的外壳并且如果使用了错误的外壳会崩溃,该怎么办?
用户可能会迷路并且破坏东西-不信任用户:-)我进行了无数次攻击,这些攻击依赖于用户对路径执行错误的操作-通常以错误的顺序进行操作-因此我可以颠覆正常的脚本调用。
是的,我知道如果您自己编写了脚本,则可以正确地声称您已经整理了自己的路径,但是解释器无法做出这些决定。
$PATH
。。没有提升的特权,如果LD_PRELOAD
使用该怎么办?PS欠佳,因为对安全性作出错误警告会损害安全性。
PATH
存在一个攻击媒介,并且没有那么多其他攻击媒介需要重新考虑整个方法?
ruby
,但这不会阻止您指定/home/user/myrubyinterpreter
是否要