18.10 自定义开机启动项的init脚本

大多数基于Linux的操作系统都使用了System-V风格的init进程管理,大量服务使用init脚本进行管理。init脚本是Linux系统用于启动系统服务的脚本,RedHat和CentOS发行版默认将这些服务启动脚本放在etcinit.d目录中。系统在启动时将根据当前的运行级(runlevel X)确定运行在etcrc.d/rcX.d目录下的脚本(都是到etcinit.d目录中的文件软链接)。

作为Linux系统管理人员,有时候需要根据具体的业务需求自己写init脚本。但是和一般的shell脚本不同,init脚本需要满足一定的格式,最基本的要求是,脚本必须接收至少两个参数:start和stop,分别用于启动和停止服务。系统在启动时所显示的很多的Starting其实是在调用脚本的start参数,如图18-3所示;系统在关机时显示的很多的Stopping则是在调用脚本的stop参数,如图18-4所示。当然,脚本可能由于功能的多样性,还可以接收更多参数。考虑到脚本良好的可读性,建议在写init脚本时,将各种参数的执行体封装成函数的格式。

18.10 自定义开机启动项的init脚本 - 图1

图18-3 开机过程中的服务启动项

18.10 自定义开机启动项的init脚本 - 图2

图18-4 关机过程中的服务停止项

关于init脚本的书写要求,下面通过分析一个简单的系统脚本yum-updatesd来总结。在搞清楚并理解透彻后,自己写init脚本就可以变得很简单了。注意,下面脚本中以##开头的部分是给出的注解。


  1. [root@localhost ~]# cat etcinit.d/yum-updatesd

  2. #!/bin/bash

  3. ##

  4. 简述一下该脚本的作用,建议有

  5. # yum Update notification daemon

  6. ##

  7. 作者的联系方式,建议有

  8. # Author: Jeremy Katz <katzj@redhat.com>

  9. ##

  10. 设置chkconfig

  11. ,一定要有。其中345

  12. 是运行级别为3

  13. 4

  14. 5

  15. 时,启动优先级是97

  16. ,关闭优先级是03

  17. # chkconfig: 345 97 03

  18. ##

  19. 更详细的描述,建议要有

  20. # description: This is a daemon which periodically checks for updates \

  21. # and can send notifications via mail, dbus or syslog.

  22. #

  23. 进程名,非必需

  24. # processname: yum-updatesd

  25. # config: etcyum/yum-updatesd.conf

  26. # pidfile: varrun/yum-updatesd.pid

  27. #

  28. ##

  29. 下面的信息不是必需的,可根据实际情况决定

  30. ### BEGIN INIT INFO

  31. # Provides: yum-updatesd

  32. # Required-Start: $syslog $local_fs messagebus

  33. # Required-Stop: $syslog $local_fs messagebus

  34. # Default-Start: 2 3 4 5

  35. # Default-Stop: 0 1 6

  36. # Short-Description: Update notification daemon

  37. # Description: Daemon which notifies about available updates via mail, dbus or

  38. # syslog. Can also be configured to automatically apply updates.

  39. ### END INIT INFO

  40. ##

  41. 引用库函数

  42. # source function library

  43. . etcrc.d/init.d/functions

  44. RETVAL=0

  45. ##

  46. 定义start

  47. 函数的动作,一定要有

  48. start() {

  49. echo -n $"Starting yum-updatesd: "

  50. daemon +19 'yum-updatesd &'

  51. RETVAL=$?

  52. echo

  53. [ $RETVAL -eq 0 ] && touch varlock/subsys/yum-updatesd

  54. }

  55. ##

  56. 定义stop

  57. 函数的动作,一定要有

  58. stop() {

  59. echo -n $"Stopping yum-updatesd: "

  60. killproc yum-updatesd

  61. echo

  62. [ $RETVAL -eq 0 ] && rm -f varlock/subsys/yum-updatesd

  63. }

  64. ##

  65. 定义restart

  66. 函数,不必需

  67. restart() {

  68. stop

  69. start

  70. }

  71. ##

  72. 脚本主体

  73. case "$1" in

  74. start)

  75. start

  76. ;;

  77. stop)

  78. stop

  79. ;;

  80. restart|force-reload|reload)

  81. restart

  82. ;;

  83. condrestart|try-restart)

  84. [ -f varlock/subsys/yum-updatesd ] && restart

  85. ;;

  86. status)

  87. status yum-updatesd

  88. RETVAL=$?

  89. ;;

  90. *)

  91. echo $"Usage: $0 {start|stop|status|restart|reload|force-reload|condrestart}"

  92. exit 1

  93. esac

  94. exit $RETVAL


按照上面脚本的规范,将前一小节中的防火墙脚本改写成init脚本,如下所示:


  1. [root@localhost ~]# cat etcinit.d/myIptables

  2. #!/bin/bash

  3. #iptables Control myIptables

  4. #Author: johnwang.wangjun@gmail.com

  5. #chkconfig: 345 97 03

  6. #description: This script is for start and stop myIptables

  7. #pidfile: varrun/myIptables.pid

  8. #DEFINE VARIABLES

  9. HTTP_PORT=80

  10. SECURE_HTTP_PORT=443

  11. SSH_PORT=22

  12. DNS_PORT=53

  13. ALLOWED_IP=192.168.61.1 #

  14. 这是笔者实验环境中主机的地址,读者需要修改成自己的IP

  15. IPTABLES=/sbin/iptables

  16. RM=/bin/rm

  17. PIDFILE=varrun/myIptables.pid

  18. start() {

  19. if [ -f $PIDFILE ]; then

  20. echo "myIptables is running"

  21. exit 1

  22. else

  23. touch $PIDFILE

  24. fi

  25. #FLUSH IPTABLES

  26. $IPTABLES -F

  27. $IPTABLES -X

  28. #DEFINE DEFAULT ACTION

  29. $IPTABLES -P INPUT DROP

  30. $IPTABLES -P OUTPUT DROP

  31. #DEFINE INPUT CHAINS

  32. $IPTABLES -A INPUT -p icmp --icmp-type any -j ACCEPT

  33. $IPTABLES -A INPUT -s localhost -d localhost -j ACCEPT

  34. $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

  35. $IPTABLES -A INPUT -p tcp --dport $SSH_PORT -j ACCEPT

  36. #DEFINE OUTPUT CHAINS

  37. $IPTABLES -A OUTPUT -p icmp --icmp any -j ACCEPT

  38. $IPTABLES -A OUTPUT -s localhost -d localhost -j ACCEPT

  39. $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

  40. $IPTABLES -A OUTPUT -p tcp -m state --state NEW --dport $HTTP_PORT -j ACCEPT

  41. $IPTABLES -A OUTPUT -p tcp --dport $SECURE_HTTP_PORT -j ACCEPT

  42. $IPTABLES -A OUTPUT -p udp --dport $DNS_PORT -j ACCEPT

  43. $IPTABLES -A OUTPUT -p tcp --dport $SSH_PORT -j ACCEPT

  44. echo "Start myIptables OK"

  45. }

  46. stop() {

  47. if [ ! -f $PIDFILE ]; then

  48. echo "myIptables is already stopped"

  49. exit 1

  50. else

  51. $RM $PIDFILE

  52. fi

  53. #FLUSH IPTABLES

  54. $IPTABLES -F

  55. $IPTABLES -X

  56. #DEFINE DEFAULT ACTION

  57. $IPTABLES -P INPUT ACCEPT

  58. $IPTABLES -P OUTPUT ACCEPT

  59. echo "Stop myIptables OK"

  60. }

  61. case "$1" in

  62. start)

  63. start

  64. ;;

  65. stop)

  66. stop

  67. ;;

  68. reload|restart)

  69. stop

  70. start

  71. ;;

  72. *)

  73. echo "Usage: $0 {start|stop|restart|reload}"

  74. exit 1

  75. esac


注意,该脚本应该放在etcinit.d目录中,并且要有可执行权限。

编写完成后,使用chkconfig命令添加该脚本成为系统服务。注意:如果系统本身启动了iptables服务,可以将该启动项停用。


#

停用系统默认iptables

服务

[root@localhost ~]# chkconfig —level 345 iptables off

#

添加myIptables

为系统服务

[root@localhost ~]# chkconfig —add myIptables

#

使用chkconfig

添加为系统服务后,看到默认345

是开启的,这和脚本中的设置是一致的

[root@localhost ~]# chkconfig —list | grep myIptables

myIptables 0:off 1:off 2:off 3:on 4:on 5:on 6:off

#

启动优先级确实是97

[root@localhost ~]# ls etcrc.d/rc3.d/ | grep myIptables

S97myIptables

#

关闭优先级确实是3

[root@localhost ~]# ls etcrc.d/rc2.d/ | grep myIptables

K03myIptables


添加完成后,就可以使用service命令来管理该服务了。


  1. [root@localhost ~]# service myIptables start

  2. Start myIptables OK

  3. [root@localhost ~]# service myIptables restart

  4. Stop myIptables OK

  5. Start myIptables OK

  6. [root@localhost ~]# service myIptables stop

  7. Stop myIptables OK