BSD rc.d脚本编程实战
上一页 |  | 下一页

# 3 虚拟的脚本

下面的脚本是用来在每次系统启动时发出一个信息：

    #!/bin/sh

    . /etc/rc.subr

    name="dummy"
    start_cmd="${name}_start"
    stop_cmd=":"

    dummy_start()
    {
        echo "Nothing started."
    }

    load_rc_config $name
    run_rc_command "$1"

需要注意的是：

  一个解释性的脚本应该以一行魔幻的 “shebang” 行开头。 该行指定了脚本的解析程序。由于 shebang 行的作用， 假如再有可执行位的设置， 脚本就能象一个二进制程序一样被精确地调用执行。 （请参考 chmod(1)。） 例如， 一个系统管理员可以从命令行手动运行我们的脚本：

      # /etc/rc.d/dummy start

  > 注意: 为了使 `rc.d` 框架正确地管理脚本， 它的脚本需要用 sh(1) 语言编写。 如果你的某个服务或 port 套件使用了二进制控制程序或是用其它语言编写的例程， 请将其组件安装到 `/usr/sbin`（相对于系统） 或 `/usr/local/sbin`（相对于ports）， 然后从合适的 `rc.d` 目录的某个 sh(1) 脚本调用它。

  > 提示: 如果你想知道为什么 `rc.d` 脚本必须用 sh(1) 语言编写的细节，先看下 `/etc/rc` 是如何依靠 `run_rc_script` 调用它们， 然后再去学习 `/etc/rc.subr` 下 `run_rc_script` 的相关实现。

  在 `/etc/rc.subr` 下， 有许多定义过的 sh(1) 函数可供每个 `rc.d` 脚本使用。这些函数在 rc.subr(8) 中都有说明。尽管理论上可以完全不使用 rc.subr(8) 来编写一个 `rc.d` 脚本，但它的函数已经证明了它真的很方便， 并且能使任务更加的简单。所以所有人在编写 `rc.d` 脚本时都会求助于 rc.subr(8) 也不足为奇了。当然我们也不例外。

  一个 `rc.d` 脚本在其调用 rc.subr(8) 函数之前必须先 “source” `/etc/rc.subr`（用 “`.`”将其包含进去）， 而使 sh(1) 程序有机会来获悉那些函数。 首选风格是在脚本的最开始 source `/etc/rc.subr` 文件。

  > 注意: 某些有用的与联网有关的函数由另一个被包含进来的文件提供， `/etc/network.subr` 文件。

  强制的变量 `name` 指定我们脚本的名字。 这是 rc.subr(8) 所强调的。也就是， 每个 `rc.d` 脚本在调用 rc.subr(8) 的函数之前必须设置 `name` 变量。

  现在是时候来为我们的脚本一次性选择一个独一无二的名字了。 在编写这个脚本的时我们将在许多地方用到它。在开始之前， 我们来给脚本文件也取个相同的名字。

  > 注意: 当前的 `rc.d` 脚本风格是把值放在双引号中来给变量赋值。 请记住这只是个风格问题，可能并不总是这样。 你可以在只是简单的并不包括 sh(1) 元字符的词句中放心地省略掉引号， 而在某些情况下你将需要使用单引号以防止 sh(1) 对任何的变量的解释。 程序员是可以灵巧地由风格惯例获悉其语法以及使用的。

  rc.subr(8) 背后主要的构思是 `rc.d` 脚本提供处理程序，或者方法，来让 rc.subr(8) 调用。特别是，`start`， `stop`，以及其它的 `rc.d` 脚本参数都是这样被处理的。方法是存储在一个以 ``argument_cmd`` 形式命名的变量中的 sh(1) 表达式，该 `argument` 对应着脚本命令行中所特别指定的参数。我们稍后将看到 rc.subr(8) 是如何为标准参数提供默认方法的。

  > 注意: 为了让 `rc.d` 中的代码更加统一， 常见的是在任何适合的地方都使用 `${name}` 形式。 这样一来，可以轻松地将一些代码从一个脚本拷贝到另一个中使用。

  我们应谨记 rc.subr(8) 为标准参数提供了默认的方法。 因此，如果希望它什么都不做的话，我们必须使用无操作的 sh(1) 表达式来改写标准的方法。
  比较复杂的方法主体可以用函数来实现。 在能够保证函数名有意义的情况下，这是个很不错的想法。

  > 重要: 强烈推荐给我们脚本中所定义的所有函数名都添加类似 `${name}` 这样的前缀，以使它们永远不会和 rc.subr(8) 或其它公用包含文件中的函数冲突。

  这是在请求 rc.subr(8) 载入 rc.conf(5) 变量。 尽管我们这个脚本中使用的变量并没有被其它地方使用，但由于 rc.subr(8) 自身所控制着的 rc.conf(5) 变量存在的原因，仍然推荐脚本去装载 rc.conf(5)。
  通常这是 `rc.d` 脚本的最后一个命令。 它调用 rc.subr(8) 体系使用我们脚本所提供的变量和方法来执行相应的请求动作。

上一页 | 起始页 | 下一页
任务描述 |  | 可配置的虚拟脚本

本文档和其它文档可从这里下载：ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

如果对于FreeBSD有问题，请先阅读文档，如不能解决再联系<questions@FreeBSD.org>.
关于本文档的问题请发信联系 <doc@FreeBSD.org>.