| 一个解释性的脚本应该以一行魔幻的
“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)
体系使用我们脚本所提供的变量和方法来执行相应的请求动作。 |