8. 给予 rc.d 脚本更多的灵活性
上一页 |  | 下一页

## 8. 给予 rc.d 脚本更多的灵活性

当进行启动或停止的调用时，`rc.d` 脚本应该作用于其所负责的整个子系统。例如， `/etc/rc.d/netif` 应该启动或停止 rc.conf(5) 中所描述的全部网络接口。每个任务都唯一地听从一个如 `start` 或 `stop` 这样的单独命令参数的指示。在启动和停止之间的时间， `rc.d` 脚本帮助管理员控制运行中的系统， 并其在需要的时候它将产生更多的灵活性和精确性。举个例子， 管理员可能想在 rc.conf(5) 中添加一个新网络接口的配置信息， 然后在不妨碍其它已存在接口的情况下将其启动。 在下次管理员可能需要关闭一个单独的网络接口。在魔幻的命令行中， 对应的 `rc.d` 脚本调用一个额外的参数， 网络接口名即可。

幸运的是，rc.subr(8) 允许传递任意多（取决于系统限制）的参数给脚本的方法。 由于这个原因，脚本自身的改变可以说是微乎其微。

rc.subr(8) 如何访问到附加的命令行参数呢？直接获取么？ 并非是无所不用其极的。首先，sh(1) 函数没有访问到调用者的定位参数，而 rc.subr(8) 只是这些函数的容器。其次，`rc.d` 指令的一个好的风格是由主函数来决定将哪些参数传递给它的方法。

所以 rc.subr(8) 提供了如下的方法： `run_rc_command` 传递其所有参数但将第一个参数逐字传递到各自的方法。首先， 发出以方法自身为名字的参数：`start`， `stop`，等等。这会被 `run_rc_command` 移出， 这样命令行中原本 `$2` 的内容将作为 `$1` 来提供给方法，等等。

为了说明这点，我们来修改原来的虚拟脚本， 这样它的信息将取决于所提供的附加参数。从这里出发：

#!/bin/sh . /etc/rc.subr name="dummy" start_cmd="${name}_start" stop_cmd=":" kiss_cmd="${name}_kiss" extra_commands="kiss" dummy_start() { if [ $# -gt 0 ]; then echo "Greeting message: $*" else echo "Nothing started." fi } dummy_kiss() { echo -n "A ghost gives you a kiss" if [ $# -gt 0 ]; then echo -n " and whispers: $*" fi case "$*" in *[.!?]) echo ;; *) echo . ;; esac } load_rc_config $name run_rc_command "$@"

能注意到脚本里发生了那些实质性改变么？

| 你输入的所有在 `start` 之后的参数可以被当作各自方法的定位参数一样被终结。 我们可以根据我们的任务、技巧和想法来以任何方式使用他们。 在当前的例子中，我们只是以下行中字符串的形式传递参数给 echo(1) 程序 — 注意 `$*` 是有双引号的。这里是脚本如何被调用的： `#` `/etc/rc.d/dummy start` Nothing started. `#` `/etc/rc.d/dummy start Hello world!` Greeting message: Hello world!
| 同样用于我们脚本提供的任何方法，并不仅限于标准的方法。 我们已经添加了一个自定义的叫做 `kiss` 的方法， 并且它给附加参数带来的戏耍决不亚于 `start`。 例如： `#` `/etc/rc.d/dummy kiss` A ghost gives you a kiss. `#` `/etc/rc.d/dummy kiss Once I was Etaoin Shrdlu...` A ghost gives you a kiss and whispers: Once I was Etaoin Shrdlu...

如果我们只是传递所有附加参数给任意的方法， 我们只需要在脚本的最后一行我们调用 `run_rc_command` 的地方， 用 `"$@` 代替 `"$1"` 即可。

### 重要:

一个 sh(1) 程序员应该是可以理解 `$*` 和 `$@` 的微妙区别只是指定全部定位参数的不同方法。 关于此更深入的探讨，可以参考这个很好的 sh(1) 脚本编程手册。在你完全理解这些表达式的意义之前请不要使用它们， 因为误用它们将给脚本引入缺陷和不安全的弊端。

### 注意:

现在 `run_rc_command` 可能有个缺陷， 它将影响保持参数之间的原本边界。也就是， 带有嵌入空白的参数可能不会被正确处理。该缺陷是由于对 `$*` 的误用。

上一页 |  | 下一页
7. 链接脚本到 rc.d 框架 | 起始页 | 9. 进一步阅读

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

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