加入收藏 | 设为首页 | 会员中心 | 我要投稿 安卓应用网 (https://www.0791zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

LINUX实操:如何写SysV服务管理脚本

发布时间:2020-05-22 16:22:29 所属栏目:Linux 来源:互联网
导读:介绍《LINUX实操:如何写SysV服务管理脚本》开发教程,希望对您有用。

《LINUX实操:如何写SysV服务管理脚本》要点:
本文介绍了LINUX实操:如何写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作风的服务启动脚本有以下几个特性:

  1. 一般都放在/etc/rc.d/init.d目录下.
  2. 这类脚本要求能接受start、stop、restart、status等参数来管理服务进程.
  3. 基本上都会加载/etc/rc.d/init.d/functions文件,因为该文件中定义了几个对进程管理非常有用的函数.
  4. 基本上都会加载/etc/sysconfig目录下的同名文件.此目录下的服务同名文件一般都是为服务管理脚本提供选项参数的.例如/etc/sysconfig/httpd.
  5. 在脚本的顶端,需要加上# 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脚本要具备的才能

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

  1. 启动进程时:
    • 要求能够检测进程是否已在运行.这包含检测pid文件是否存在、/proc目录下是否有进程pid值对应的目录.
    • 应该为程序创建锁文件,路径一般在/var/lock/subsys目录下.
    • 如果使用daemon函数启动进程,允许"--user"指定程序的运行身份.
    • 有些进程启动时需要依赖于其他进程,如NFS启动时依赖于rpcbind服务、mountd服务等,所以在NFS脚本中必须能够检测并启动这些依赖服务.
  2. 关闭进程时:
    • 要求能够检测进程是否已在运行.同样是检测pid文件是否存在,/proc目录下是否有pid对应的目录.要注意,只有/proc目录下没有了对应目录,才表示进程已死,但pid文件仍可能存在,例如kill -9就会出现这种问题.
    • 可以使用functions文件中的killproc函数杀进程,也可以直接使用kill或killall.
    • 为了让脚本更完善,杀进程时应该多次检测进程是否真的已经杀死.
    • 杀死进程的最后,必须要删除pid文件和锁文件.
    • 对于有依赖性的服务,考虑是否也应该杀死它们.
  3. 服务重读配置文件时(reload):
    • 对于非终端进程,发送HUP信号的作用是重读配置文件,而不会中断进程.
    • 为了标准,应该找出"master"进程的pid,并向其发送HUP信号.一般来说,服务的子进程或线程不会也没必要读取配置文件.为了方便或投篮,可以直接向所有进程发送HUP信号.
    • 最好在发送HUP信号前,也检查进程是否已在运行.当然,对于reload来说,这无所谓.
    • 如果待管理程序支持配置文件的语法检查,在发送HUP信号前,应该检查语法是否错误.
    • 实在无法实现重读配置文件的功能,应该让其和restart的功能一致,一般这也是"force-reload"的功能.
  4. 重启服务时:
    • 一般来说,就是先stop,再start.
  5. 查看status时:
    • 除非有额外的状态显示需求,否则/etc/init.d/functions中的status函数已经足够完美了.

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

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

因为网上以及/etc/init.d/下服务启动脚本示例太多了,所以本文不单独写这类脚本,而是从几个脚本中抽出比拟经典的部分,分别介绍start,stop,reload和status的写法.

1.3 start函数阐发

以httpd的服务管理脚本/etc/init.d/httpd为例.

start() {
    echo -n $"Starting $prog: "
    LANG=$HTTPD_LANG daemon --pidfile=${pidfile} $httpd $OPTIONS
    RETVAL=$?
    echo
    [ $RETVAL = 0 ] && touch ${lockfile}
    return $RETVAL
}

函数首先输出"Starting $prog"信息,再使用daemon启动"$httpd"法式.

在daemon语句中,"--pidfile"是daemon的参数,该参数为daemon检测pid文件是否存在,"$httpd"进程是否已在运行.注意,这个"--pidfile"是写在"$httpd"前面的,表现这是daemon的参数,而非"$httpd"的启动参数.

检测完成后,启动程序.程序的启动命令从"$httpd"参数开始,"$OPTIONS"是"$httpd"的启动选项.一般呈现"$OPTIONS"这个字眼,很可能加载了/etc/sysconfig目录下的同名文件,目的是提供程序启动参数.

如果启动成功,则会daemon函数会调用functions中的success函数显示"[ OK ]",不然会显示"[ FAILED ]".

最后,如果启动胜利,则会创建该进程的锁文件"$lockfile".锁文件一般都在/var/lock/subsys目录下.

很多时候,治理的进程也有"--pidfile"类似的选项.例如下面的启动语句:

daemon --pidfile $pidfile $processname --pidfile=$pidfile

两个"--pidfile"选项,但他们的作用是纷歧样的.第一个"--pidfile"是daemon函数的参数,以便daemon能够检测该文件中的pid进程是否已在运行.第二个"--pidfile"是"$processname"的启动参数,启动时会创建此文件作为pid文件.

再看一个不使用daemon函数治理进程启动动作的示例.以下是/etc/init.d/sshd中的start函数内容.

start()
{
        [ -x $SSHD ] || exit 5
        [ -f /etc/ssh/sshd_config ] || exit 6
        # Create keys if necessary
        if [ "x${AUTOCREATE_SERVER_KEYS}" != xNO ]; then
                do_rsa_keygen
                if [ "x${AUTOCREATE_SERVER_KEYS}" != xRSAONLY ]; then
                        do_rsa1_keygen
                        do_dsa_keygen
                fi
        fi
        echo -n $"Starting $prog: "
        $SSHD $OPTIONS && success || failure
        RETVAL=$?
        [ $RETVAL -eq 0 ] && touch $lockfile
        echo
        return $RETVAL
}

前面多了一大段,这和服务启动脚本的框架无关,是程序自身要求的,但作用很简单.无非便是判断下程序是否可执行,配置文件是否存在,是否要创建服务端主机验证阶段的密钥对,也便是/etc/ssh/ssh_host_{rsa,dsa}_key等几个文件.

再下才是服务启动脚本中的通用逻辑部门.输出一段信息,然后启动程序,创建锁文件.但这里没有使用daemon函数管理,所以这里配合了success和failure函数以便人性化显示"[ OK ]"或"[ FAILED ]".

1.4 stop函数阐发

仍然以/etc/init.d/httpd中的stop函数为例.

# When stopping httpd,a delay (of default 10 second) is required
# before SIGKILLing the httpd parent; this gives enough time for the
# httpd parent to SIGKILL any errant children.
stop() {
    status -p ${pidfile} $httpd > /dev/null
    if [[ $? = 0 ]]; then
        echo -n $"Stopping $prog: "
        killproc -p ${pidfile} -d ${STOP_TIMEOUT} $httpd
    else
        echo -n $"Stopping $prog: "
        success
    fi
    RETVAL=$?
    echo
    [ $RETVAL = 0 ] && rm -f ${lockfile} ${pidfile}
}

前面加了一段注释,大致意思是说这里杀死进程的行为和httpd自带的apachectl工具停止服务的命令"apachectl -k stop"的行为是不同的.之所以我要把这一段也贴上来,也就是为了说明这一点.有些服务程序自带进程管理工具,亦或是使用functions中的函数,完全由我们本身决定.

再看stop函数的逻辑.首先使用"status"函数检查进程的状态,如果进程已在运行,则使用killproc函数杀掉它,否则表现进程未运行或进程已死,但pid文件还存在.所以,在最后删掉pidfile和lockfile.

必要注意的是,killproc杀进程时,能保证pidfile同时被删除.但它不负责lockfile,而且执行stop之前曾手动执行了"kill -9"杀进程,那么进程虽然已死,但pid文件却存在.因此也仍需手动rm删除pidfile.

killproc的调用办法为:

killproc [-p $pidfile] -[d $delay] $processname [-signal]

(编辑:安卓应用网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读