我们来给之前的 “骨架” 脚本加点 “血肉”,并让它更复杂更富有特性吧。 默认的方法已能够为我们做很好的工作了, 但是我们可能会需要它们一些方面的调整。 现在我们将学习如何调整默认方法来符合我们的需要。
#!/bin/sh . /etc/rc.subr name=mumbled rcvar=mumbled_enable command="/usr/sbin/${name}" command_args="mock arguments > /dev/null 2>&1" pidfile="/var/run/${name}.pid" required_files="/etc/${name}.conf /usr/share/misc/${name}.rules" sig_reload="USR1" start_precmd="${name}_prestart" stop_postcmd="echo Bye-bye" extra_commands="reload plugh xyzzy" plugh_cmd="mumbled_plugh" xyzzy_cmd="echo 'Nothing happens.'" mumbled_prestart() { if checkyesno mumbled_smart; then rc_flags="-o smart ${rc_flags}" fi case "$mumbled_mode" in foo) rc_flags="-frotz ${rc_flags}" ;; bar) rc_flags="-baz ${rc_flags}" ;; *) warn "Invalid value for mumbled_mode" return 1 ;; esac run_rc_command xyzzy return 0 } mumbled_plugh() { echo 'A hollow voice says "plugh".' } load_rc_config $name run_rc_command "$1"
注意: 永远不要 在 command_args 包含破折号选项, 类似
-X
或--foo
这样的。command_args 的内容将出现在最终命令行的末尾,因此它们可能是紧接在 ${name}_flags 中所列出的参数后面; 但大多的命令将不能识别出普通参数后的破折号选项。 更好的传递附加给 $command 的选项的方式是添加它们到 ${name}_flags 的起始处。另一种方法是像后文所示的那样来修改 rc_flags。
注意: 事实上,rc.subr(8) 在启动一个守护进程前还会使用 pidfile 进程文件来查看它是否已经在运行。使用了
faststart
参数可以跳过这个检查步骤。
注意: 来自 rc.subr(8) 的默认方法,通过使用
forcestart
作为脚本的参数, 可以强制性地跳过预先需要的检查。
SIGHUP
信号。 另一个信号是发送给守护进程以停止该进程;默认情况下是
SIGTERM
信号,但这是可以通过设置 sig_stop 来进行适当更改的。注意: 信号名称应当以不包含 SIG 前缀的形式指定给 rc.subr(8),就如范例中所示的那样。 FreeBSD 版本的 kill(1) 程序能够识别出 SIG 前缀,不过其它系统版本的就不一定了。
注意: 如果我们需要的话,用自定义的 argument_cmd 改写默认的方法,并不妨碍我们仍然使用 argument_precmd 和 argument_postcmd。 特别是,前者便于检查自定义的方法, 以及执行自身命令之前所遇到更严密的条件。于是,将 argument_precmd 和 argument_cmd 一起使用,使我们合理地将检查从动作中独立了出来。
别忘了你可以将任意的有效的 sh(1) 表达式插入到方法和你定义的 pre- 与 post-commands 命令中。 在大部分情况下,调用函数使实际任务有好的风格, 但千万不要让风格限制了你对其幕后到底是怎么回事的思考。
注意:
reload
是个特别的命令。一方面, 它有一个在 rc.subr(8) 中预置的方法。另一方面,reload
命令默认是不被提供的。 理由是并非所有的守护进程都使用同样的重载方法, 并且有些守护进程根本没有任何东西可重载的。所以显而易见, 我们需要去询问都提供了哪些的内建功能。我们可以通过 extra_commands 来这样做。我们从
reload
的默认方法得到了什么呢? 守护进程常常在收到一个信号后重新载入它们的配置 ── 一般来说,也就是SIGHUP
信号。因此 rc.subr(8) 尝试发送一个信号给守护进程来重载它。 该信号一般预设为SIGHUP
, 但是如果必要的话可以通过 sig_reload 变量来自定义它。
plugh
和 xyzzy
。 我们看到它们在 extra_commands
中被列出来了, 并且现在是时候给它们提供方法了。xyzzy
的方法是内联的而 plugh
的是以 mumbled_plugh
形式完成的函数。非标准命令在启动或停止的时候不被调用。 通常它们是为了系统管理员的方便。它们还能被其它的子系统所使用, 例如,devd(8),前提是 devd.conf(5) 中已经指定了。
全部可用命令的列表,当脚本不加参数地调用时,在 rc.subr(8) 打印出的使用方法中能够找到。例如, 这就是供学习的脚本用法的内容:
# /etc/rc.d/mumbled Usage: /etc/rc.d/mumbled [fast|force|one](start|stop|restart|rcvar|reload|plugh|xyzzy|status|poll)
checkyesno
。
它以一个变量名作为参数并返回一个为零的退出值, 当且仅当该变量设置为 YES,或 TRUE,或 ON,或 1,区分大小写;否则返回一个非零的退出值。
在第二种情况中,函数测试变量的设置为 NO, FALSE,OFF,或 0,区分大小写;
如果变量包含别的内容的话它打印一条警告信息,例如,垃圾。切记对 sh(1) 而言零值意味着真而非零值意味着假。
重要:
checkyesno
函数使用一个 变量名。不要扩大含义将变量的 值 传递给它; 否则它不会如你预期那样的工作。下面是
checkyesno
的合理使用范围:if checkyesno mumbled_enable; then foo fi相反地,以下面的方式调用
checkyesno
是不会工作的 -- 至少是不会如你预期的那样:if checkyesno "${mumbled_enable}"; then foo fi
debug
,info
, warn
,以及 err
。 后者以指定的代码值退出脚本。注意: 然而,当给一个参数使用 force 前缀的时候,如
forcestart
,rc.subr(8) 会听从命令行指示而忽略那些退出值最后仍然调用所有的命令。
本文档和其它文档可从这里下载:ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.
如果对于FreeBSD有问题,请先阅读文档,如不能解决再联系<questions@FreeBSD.org>.
关于本文档的问题请发信联系 <doc@FreeBSD.org>.