17.1 分析一个系统脚本

让我们利用对系统管理命令的了解,一起分析一个系统脚本吧。最简单易懂的脚本之一是“killall”,[1]用于在系统关闭时暂停正在运行的进程。

样例 17-12. killall脚本,来自/etc/rc.d/init.d

#!/bin/sh

# --> 本文档作者添加的注释为“#-->”。

# --> 这是'rc'脚本软件包的一部分。
# --> 该脚本由Miquel van Smoorenburg所撰,<miquels@drinkel.nl.mugnet.org>.

# --> 该脚本似乎仅用于特定的Red Hat / FC系统
# --> (可能不会出现在其他发行版中)。

#  关闭所有非必需但仍在运行的服务。
#  (其实并不应该有,所以这只是一个健全性检查)

for i in /var/lock/subsys/*; do
        # --> 标准的for/in循环,但“do”写在同一行,
        # --> 有必要加";"。
        # 检查是否脚本还在那里。
        [ ! -f $i ] && continue
        # --> 这是一个“与列表”的巧妙运用,等价于:
        # --> if [ ! -f "$i" ]; then continue

        # 获取子系统名称。
        subsys=${i#/var/lock/subsys/}
        # --> 匹配变量名,在本例中是文件名。
        # --> 完全等价于 subsys=`basename $i`。

        # -->  从锁文件中获取
        # -->  (如果存在锁文件,
        # -->   那就证明了进程还在运行)。
        # -->  请参见上面的“锁文件”条目。


        # 关闭子系统。
        if [ -f /etc/rc.d/init.d/$subsys.init ]; then
           /etc/rc.d/init.d/$subsys.init stop
        else
           /etc/rc.d/init.d/$subsys stop
        # -->  挂起正在运行的工作和守护进程。
        # -->  注意"stop"是一个位置参数,
        # -->  并不是一个shell内置程序。
        fi
done

仔细看看还是能读懂的。除了一点变量匹配的小技巧,没有新的东西。

练习 1.请分析位于/etc/rc.d/init.d目录下的halt脚本。它比killall稍长,但概念相似。请复制将这个脚本拷贝到主目录中的某个地方进行试验(不要root用户身份运行它)。可以使用-vn标志(sh -vn scriptname)模拟运行脚本。在此过程中,你可以添加更多的注释。把命令改成echo

练习 2.请观察/etc/rc.d/init.d下一些更复杂的脚本,试着至少理解它们的一部分。按照上面的过程来分析它们。为了获得更多的信息,你还可以检查/usr/share/doc/initscripts-?.??中的sysvinitfile文件,它们是“初始脚本”文档中的一部分。

注记

[1]请不要将killall系统脚本与位于/usr/bin中的killall命令相混淆。

最后更新于