舍邦和路径


22

为什么shebang需要一条路?

错误

#!ruby

正确

#!/usr/local/bin/ruby

#!/usr/bin/env ruby

操作系统应该具有有关已注册命令路径的信息,为什么还希望它被给出?

Answers:


22

可能是为了使内核更简单。我认为内核从未搜索过您的路径以找到可执行文件。这是由C库处理的。 #!处理是在不使用标准C库的内核中完成的。

另外,我认为内核不了解您的路径是什么。 $PATH是一个环境变量,只有进程具有环境。内核没有。我想它可以访问执行该执行程序的环境,但是我认为内核中当前没有任何东西可以像这样访问环境变量。


5

您可以PATH使用来搜索语义env,因此:

#!/usr/bin/env ruby  

具有您想要的语义

#!ruby

视之为PATH最佳做法的原因是该脚本无法对PATH环境变量的内容进行任何假设,从而破坏了二进制文件的“顺序依赖模型”,其中

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

每个级别都不应该假设序列中后面的二进制文件存在,这些二进制文件更“应用”,而可能更早地依赖二进制文件,这些二进制文件更“基础”。PATH变量倾向于从应用到基本,这与上面的自然依赖相反。

为了说明问题,请问自己一个问题,如果脚本中~/bin的脚本/usr/local/bin调用Ruby中的脚本,会发生什么?该脚本是否应该取决于OS的安装版本/usr/bin/ruby,或者取决于用户恰巧拥有的个人副本~/bin/rubyPATH搜索给出了与后者相关的不可预测的语义(可能~/bin/ruby是断开的符号链接),同时烘烤了#!给出后者的路径。

实际上并没有任何其他与平台无关的“操作系统...有关已注册命令路径的信息”,因此最简单的方法是坚持使用中提供的路径#!


0

我相信这样可以在您需要或想要时指定备用解释器。例如:

#!/home/user/myrubyinterpreter

在shell脚本中更常见:

#!/bin/bash
#!/bin/sh
#!/bin/dash
#!/bin/csh

4
但是,为什么要这样做呢?您可以直接使用来运行ruby ruby,但这不会阻止您指定/home/user/myrubyinterpreter是否要
Michael Mrozek

迈克尔的观点正是我要问的。
sawa

0

摘自Classic Shell Scripting书:

Shell脚本通常以开头#! /bin/sh。如果您/bin/sh不符合POSIX,请使用指向POSIX兼容的shell的路径。还有一些底层的“陷阱”需要注意:

  • 您必须知道要运行的解释器的完整路径名。这可以防止跨供应商的可移植性,因为不同的供应商将事物放置在不同的位置(例如/bin/awkvs /usr/bin/awk)。

-2

还有其他原因,但是从安全角度来看,我永远不会希望脚本对正确的路径进行假设。如果错了,并且运行了错误的shell或解释器怎么办?被恶意用户插入的一个?或者,如果它依赖于特定的外壳并且如果使用了错误的外壳会崩溃,该怎么办?

用户可能会迷路并且破坏东西-不信任用户:-)我进行了无数次攻击,这些攻击依赖于用户对路径执行错误的操作-通常以错误的顺序进行操作-因此我可以颠覆正常的脚本调用。

是的,我知道如果您自己编写了脚本,则可以正确地声称您已经整理了自己的路径,但是解释器无法做出这些决定。


仅当脚本以提升的特权运行时,才需要考虑此问题。但这并不常见,因为shebang和setxid的配合不好,而且还有更多需要担心的事情$PATH。没有提升的特权,如果LD_PRELOAD使用该怎么办?PS欠佳,因为对安全性作出错误警告会损害安全性。
吉尔斯(Gilles)'所以

您关于setxid的观点是正确的,但是它是非常有用的攻击媒介,因此绝对不是虚假的警告
罗里·阿尔索普

1
您能否举一个例子,说明PATH存在一个攻击媒介,并且没有那么多其他攻击媒介需要重新考虑整个方法?
吉尔斯(Gilles)“所以,别再邪恶了”,

@Gilles-当然,+ 1是一个好点,好像它已损坏,也许还有其他方法同样有效,但是就可以修复的问题而言,这很容易。
罗里·阿尔索普
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.