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

  当进行启动或停止的调用时,rc.d 脚本应该作用于其所负责的整个子系统。例如, /etc/rc.d/netif 应该启动或停止 rc.conf(5) 中所描述的全部网络接口。每个任务都唯一地听从一个如 startstop 这样的单独命令参数的指示。在启动和停止之间的时间, 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 传递其所有参数但将第一个参数逐字传递到各自的方法。首先, 发出以方法自身为名字的参数:startstop,等等。这会被 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(1)
                echo "Greeting message: $*"
        else
                echo "Nothing started."
        fi
}

dummy_kiss()
{
        echo -n "A ghost gives you a kiss"
        if [ $# -gt 0 ]; then(2)
                echo -n " and whispers: $*"
        fi
        case "$*" in
        *[.!?])
                echo
                ;;
        *)
                echo .
                ;;
        esac
}

load_rc_config $name
run_rc_command "$@"(3)

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

(1)
你输入的所有在 start 之后的参数可以被当作各自方法的定位参数一样被终结。 我们可以根据我们的任务、技巧和想法来以任何方式使用他们。 在当前的例子中,我们只是以下行中字符串的形式传递参数给 echo(1) 程序 ── 注意 $* 是有双引号的。这里是脚本如何被调用的:
# /etc/rc.d/dummy start
Nothing started.
# /etc/rc.d/dummy start Hello world!
Greeting message: Hello world!
(2)
同样用于我们脚本提供的任何方法,并不仅限于标准的方法。 我们已经添加了一个自定义的叫做 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...
(3)
如果我们只是传递所有附加参数给任意的方法, 我们只需要在脚本的最后一行我们调用 run_rc_command 的地方, 用 "$@ 代替 "$1" 即可。

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

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

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

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