如何写SysV服务管理脚本

1.1 SysV脚本的特性
1.2 SysV脚本要具备的能力
1.3 start函数分析
1.4 stop函数分析
1.5 reload函数分析
1.6 status、restart、force-reload等
1.7 结束语

SysV服务管理脚本和/etc/rc.d/init.d/functions文件中的几个重要函数(包括daemon,killproc,status以及几个和pid有关的函数)"关系匪浅"。本人已对该文件做了极详细的分析和说明,参考functions文件详细分析和说明

1.1 SysV脚本的特性

SysV风格的服务启动脚本有以下几个特性:

一般都放在/etc/rc.d/init.d目录下。

这类脚本要求能接受start、stop、restart、status等参数来管理服务进程。

基本上都会加载/etc/rc.d/init.d/functions文件,因为该文件中定义了几个对进程管理非常有用的函数。

基本上都会加载/etc/sysconfig目录下的同名文件。此目录下的服务同名文件一般都是为服务管理脚本提供选项参数的。例如/etc/sysconfig/httpd。

在脚本的顶端,需要加上# chkconfig和# description两行。chkconfig行定义的是该脚本被chkconfig工具管理时的主要依据,包括开机和关机时的启动、关闭顺序,以及运行在哪些运行级别。description是该脚本的描述性语句。虽然这两行以"#"开头,但必不可少。

例如,/etc/init.d/httpd脚本的前面几行内容如下:

#!/bin/bash # # httpd Startup script for the Apache HTTP Server # # chkconfig: - 85 15 # description: The Apache HTTP Server is an efficient and extensible \ # server implementing the current HTTP standards. # processname: httpd # config: /etc/httpd/conf/httpd.conf # config: /etc/sysconfig/httpd # pidfile: /var/run/httpd/httpd.pid # # Source function library. . /etc/rc.d/init.d/functions if [ -f /etc/sysconfig/httpd ]; then # 判断后再加载 . /etc/sysconfig/httpd fi 1.2 SysV脚本要具备的能力

要使用脚本管理服务进程,该脚本还要求具备以下能力,且处理逻辑越完善,脚本就越完美。

启动进程时:

要求能够检测进程是否已在运行。这包括检测pid文件是否存在、/proc目录下是否有进程pid值对应的目录。

应该为程序创建锁文件,路径一般在/var/lock/subsys目录下。

如果使用daemon函数启动进程,允许"--user"指定程序的运行身份。

有些进程启动时需要依赖于其他进程,如NFS启动时依赖于rpcbind服务、mountd服务等,所以在NFS脚本中必须能够检测并启动这些依赖服务。

关闭进程时:

要求能够检测进程是否已在运行。同样是检测pid文件是否存在,/proc目录下是否有pid对应的目录。要注意,只有/proc目录下没有了对应目录,才表示进程已死,但pid文件仍可能存在,例如kill -9就会出现这种问题。

可以使用functions文件中的killproc函数杀进程,也可以直接使用kill或killall。

为了让脚本更完善,杀进程时应该多次检测进程是否真的已经杀死。

杀死进程的最后,必须要删除pid文件和锁文件。

对于有依赖性的服务,考虑是否也应该杀死它们。

服务重读配置文件时(reload):

对于非终端进程,发送HUP信号的作用是重读配置文件,而不会中断进程。

为了标准,应该找出"master"进程的pid,并向其发送HUP信号。一般来说,服务的子进程或线程不会也没必要读取配置文件。为了方便或投篮,可以直接向所有进程发送HUP信号。

最好在发送HUP信号前,也检查进程是否已在运行。当然,对于reload来说,这无所谓。

如果待管理程序支持配置文件的语法检查,在发送HUP信号前,应该检查语法是否错误。

实在无法实现重读配置文件的功能,应该让其和restart的功能一致,一般这也是"force-reload"的功能。

重启服务时:

一般来说,就是先stop,再start。

查看status时:

除非有额外的状态显示需求,否则/etc/init.d/functions中的status函数已经足够完美了。

以上并没有说明,管理多实例服务时的情况。这需要考虑额外的因素,例如程序自身是否支持多实例,支持的话是否应该写多个服务脚本分别管理各程序,配置文件是否要共享,pid文件是否能共享,搜索pid时如何避免搜索出非自身实例的pid,还要注意分配锁文件。这样的脚本写起来可能并不难,但这些因素必须要考虑。本文暂不介绍多实例的SysV脚本,因为和程序自身关联性比较强。

有了以上内容,并理解了functions文件中的函数,再看/etc/init.d/下的服务启动脚本,绝大多数都感觉很简单。因为它们的思路和框架都是一致的。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/13447.html