Linux下利用脚本创建系统服务
总体思路:写一个控制该服务启动、停止、重启的脚本(提供start、stop、restart、status选项),然后在init.d文件夹(下面包含了所有的服务脚本)中生成一份拷贝,最后在运行级别中声称符号连接(使用chkconfig命令)。
背景知识:Linux的运行级别
运行级别0:系统停机状态,系统默认运行级别不能设为0,否则不能正常启动
运行级别1:单用户工作状态,root权限,用于系统维护,禁止远程登陆
运行级别2:多用户状态(没有NFS)
运行级别3:完全的多用户状态(有NFS),登陆后进入控制台命令行模式
运行级别4:系统未使用,保留
运行级别5:X11控制台,登陆后进入图形GUI模式
运行级别6:系统正常关闭并重启,默认运行级别不能设为6,否则不能正常启动
在目录/etc/rc.d下有7个目录,它们的名字为rcN.d,分别对应7个运行的级别。在这些目录下面都是一些符号链接文件,指向init.d目录下的service脚本文件(命名为K/S+nn+服务名)。系统启动时,会根据指定的运行级别进入到相应的rcN.d目录下,按照文件名顺序检索链接文件,对于以K开头的文件,系统将终止对应的服务,而对于以S开头的文件,系统将启动对应的服务。
查看运行级别可以用 runlevel,切换到其他级别用init N,init0为关机,init6为重启,init3为命令行,init5为图形化。
背景知识:chkconfig命令
chkconfig命令用来启动,停止,查询系统服务的运行级。其实就是管理/etc/rc.d下的几个目录中的符号链接。它的语法是:
chkconfig [--list] [--type type][name] 列出相应服务,以及在每个等级下是停止还是启动
chkconfig --add name 添加新的服务
chkconfig --del name 删除服务的符号链接
chkconfig --override name 改变服务的配置
chkconfig [--level levels] [--type type] name <on|off|reset|resetpriorities>
chkconfig [--level levels] [--type type] name 指定运行等级
通过chkconfig管理的服务需要在init.d下的脚本里面添加两行或者更多的注释。第一行指出系统默认的启动等级,以及启动和停止的优先级。第二行包含了对于该服务的描述。此外,还可以使用LSB风格的初始化注释,比如设置启动的依赖等等。
具体的脚本书写内容最好的方法是参考/etc/rc.d/init.d/下面各种经典服务脚本的写法。
一个服务脚本的示例:
#!/bin/bash # # autoruntest the shell script takes care of autoruntest auto start and stop # 执行等级为2345 启动优先级为20 停止优先级为80 # chkconfig: 2345 20 80 # description: autoruntest # processname: /etc/rc.d/init.d/autoruntest EXEC_PATH=/home/paradis/app EXEC=autoruntest PID_FILE=/var/run/autoruntest.pid DAEMON=/home/paradis/code/autoruntest # Source function library. . /etc/rc.d/init.d/functions 它包含了有用的函数(killproc,status,dameon等) if ! [ -x $EXEC_PATH/$EXEC ] ; then echo "ERROR: $EXEC_PATH/$EXEC not found" exit 1 fi stop() { echo "Stoping $EXEC ..." killall $DAEMON >/dev/null usleep 100 echo "Shutting down $EXEC: [ OK ]" } start() { echo "Starting $EXEC ..." $DAEMON > /dev/null & usleep 100 echo "Starting $EXEC: [ OK ]" } restart() { stop start } case "$1" in start) start ;; stop) stop ;; restart) restart ;; status) status -p $PID_FILE $DAEMON ;; *) echo "Usage: service $EXEC {start|stop|restart|status}" exit 1 esac exit $?