Linux下编写脚本实现Daemon
2011-07-30 22:05
323 查看
在Linux(以Redhat
Linux Enterprise Edition 5.3为例)下,有时需要编写Service。Service也是程序,一般随系统启动用户不干预就不退出的程序,可以称为Service。Linux下的Service一般称为Daemon。
以上是广义的Service的定义。Linux下的服务一般放在/etc/init.d文件夹下。浏览一下这个文件夹下的文件,可以发现在Linux下编写Service一般遵循的原则。
1)真正运行的Service一般放在某个bin目录下(/bin,/usr/bin,etc)。
2)/etc/init.d文件夹下一般是shell脚本,用来控制bin目录下的Service。
3)/etc/init.d文件夹下的shell脚本一般接受至少两个参数,start和stop。还有其他常用的可选参数如status,reload,restart,等。
4)/etc/init.d文件夹下的shell脚本至少包括两行注释,一行告诉chkconfig此服务运行的runlevel,启动优先级,结束优先级。一行告诉chkconfig此服务的描述。
要理解Linux的启动过程和RunLevel,可以先浏览一下/etc/inittab文件。在/etc/inittab中定义了下面7种RunLevel。每个Service可以设置自己在哪个RunLevel下运行。可以调用/sbin/init
<runlevel>进入相应的RunLevel,比如运行/sbin/init
6就会导致系统重启。如果在某个RunLevel下某个服务不能启动,导致系统启动失败,可以进入没有配置此服务的RunLevel来禁用或修改此服务(有点类似Windows下的安全模式)。
# 0 - halt (Do NOT set initdefault to this)
# 1 - Single user mode
# 2 - Multiuser, without NFS (The same as 3, if you do not have networking)
# 3 - Full multiuser mode
# 4 - unused
# 5 - X11
# 6 - reboot (Do NOT set initdefault to this)
/etc/inittab文件下还定义了缺省RunLevel。如下,代表缺省RunLevel是5。
id:5:initdefault:
在/etc文件夹下,执行ls
-d rc*,会列出下面这些文件和目录:
rc rc0.d rc1.d rc2.d rc3.d rc4.d rc5.d rc6.d rc.d rc.local rc.sysinit
rc是一个脚本,在/etc/inittab中,会根据RunLevel执行rc
<runlevel>。rc脚本会到相应的rcN.d中去执行下面的脚本。rc.local是最后调用的脚本,可以放一些用户自定义的任务在里面。
进入rcN.d文件夹下,会发现以S和K开头的脚本的链接,S和K后面还带2位数字。其中S代表Start,K代表Kill。S开头的脚本,在rc中调用的时候会带start参数;K开头的脚本,在rc中调用的时候会带stop参数。S和K后面带的2位数字代表Service的优先级,数字越大,越后执行。这些脚本的链接的目的地多半都在/etc/init.d文件夹下。
现在一切都清晰了。我们可以通过在相应的rcN.d文件夹下按既定的规范创建/etc/init.d下脚本的软链接的方式来控制系统启动和退出时服务的启动和结束。但是用手动的方式创建软链接来管理毕竟不方便,RedHatLinux提供了chkconfig来帮助创建这些软链接。只要放在/etc/init.d下的服务控制脚本符合前面提到的chkconfig的约定(注释chkconfig 和 description),就可以用chkconfig
--add <service> chkconfig --list <service> chkconfig --del <service>等命令来控制service的启动与否。
下面是用c++语言写的一个Service,此Service在/tmp/random文件中,每隔5秒生成一个4位随机数字。通过g++
-o myrand myrand.cpp编译。然后把myrand放到/root/bin/文件夹下。
myrand.cpp
下面是一个脚本,名字是myrandservice,放在/etc/init.d文件夹下:
例子中脚本的下面两行既是给chkconfig用的。其中2345代表此服务在RunLevel
2, 3, 4, 5下开启;80代表启动优先级;50代表结束优先级。如果RunLevel处不添值,用“-”代替,则代表此服务在任何runlevel下都不会自动启动,需要手动启动。可以通过service
<service-name> start/stop/status等来控制或查询Service。
# chkconfig: 2345 80 50
# description: myrandservice is for testing how to write service in Linux
脚本中的daemon函数存在于/etc/rc.d/init.d/functions中。daemon会重定向输出到/dev/null,也会设置是否生成coredump文件。通过daemon启动的程序,即使用户退出了命令行shell,也会保证Service会运行而不会退出。在/etc/rc.d/init.d/functions中还包括其他一些有用的函数,如killproc,status等,分别用来杀掉服务和查看服务状态。
Linux Enterprise Edition 5.3为例)下,有时需要编写Service。Service也是程序,一般随系统启动用户不干预就不退出的程序,可以称为Service。Linux下的Service一般称为Daemon。
以上是广义的Service的定义。Linux下的服务一般放在/etc/init.d文件夹下。浏览一下这个文件夹下的文件,可以发现在Linux下编写Service一般遵循的原则。
Linux下编写Service一般遵循的原则
1)真正运行的Service一般放在某个bin目录下(/bin,/usr/bin,etc)。2)/etc/init.d文件夹下一般是shell脚本,用来控制bin目录下的Service。
3)/etc/init.d文件夹下的shell脚本一般接受至少两个参数,start和stop。还有其他常用的可选参数如status,reload,restart,等。
4)/etc/init.d文件夹下的shell脚本至少包括两行注释,一行告诉chkconfig此服务运行的runlevel,启动优先级,结束优先级。一行告诉chkconfig此服务的描述。
Linux的启动过程和RunLevel
要理解Linux的启动过程和RunLevel,可以先浏览一下/etc/inittab文件。在/etc/inittab中定义了下面7种RunLevel。每个Service可以设置自己在哪个RunLevel下运行。可以调用/sbin/init<runlevel>进入相应的RunLevel,比如运行/sbin/init
6就会导致系统重启。如果在某个RunLevel下某个服务不能启动,导致系统启动失败,可以进入没有配置此服务的RunLevel来禁用或修改此服务(有点类似Windows下的安全模式)。
# 0 - halt (Do NOT set initdefault to this)
# 1 - Single user mode
# 2 - Multiuser, without NFS (The same as 3, if you do not have networking)
# 3 - Full multiuser mode
# 4 - unused
# 5 - X11
# 6 - reboot (Do NOT set initdefault to this)
/etc/inittab文件下还定义了缺省RunLevel。如下,代表缺省RunLevel是5。
id:5:initdefault:
在/etc文件夹下,执行ls
-d rc*,会列出下面这些文件和目录:
rc rc0.d rc1.d rc2.d rc3.d rc4.d rc5.d rc6.d rc.d rc.local rc.sysinit
rc是一个脚本,在/etc/inittab中,会根据RunLevel执行rc
<runlevel>。rc脚本会到相应的rcN.d中去执行下面的脚本。rc.local是最后调用的脚本,可以放一些用户自定义的任务在里面。
进入rcN.d文件夹下,会发现以S和K开头的脚本的链接,S和K后面还带2位数字。其中S代表Start,K代表Kill。S开头的脚本,在rc中调用的时候会带start参数;K开头的脚本,在rc中调用的时候会带stop参数。S和K后面带的2位数字代表Service的优先级,数字越大,越后执行。这些脚本的链接的目的地多半都在/etc/init.d文件夹下。
现在一切都清晰了。我们可以通过在相应的rcN.d文件夹下按既定的规范创建/etc/init.d下脚本的软链接的方式来控制系统启动和退出时服务的启动和结束。但是用手动的方式创建软链接来管理毕竟不方便,RedHatLinux提供了chkconfig来帮助创建这些软链接。只要放在/etc/init.d下的服务控制脚本符合前面提到的chkconfig的约定(注释chkconfig 和 description),就可以用chkconfig
--add <service> chkconfig --list <service> chkconfig --del <service>等命令来控制service的启动与否。
一个例子
下面是用c++语言写的一个Service,此Service在/tmp/random文件中,每隔5秒生成一个4位随机数字。通过g++-o myrand myrand.cpp编译。然后把myrand放到/root/bin/文件夹下。
myrand.cpp
/* myrand.cpp * this program read 4 chars from /dev/random in each iteration, * and then adjust it to 0-9. Finally the 4 chars are written * to /tmp/random. This is only for testing /dev/random, and * at the same time serve as a example service. */ #include <iostream> #include <fstream> using namespace std; #include <unistd.h> int main() { while (true) { ifstream ifile("/dev/random"); char ch; char str[5]; str[4]=0; int i; for(i=0;i<4;i++) { ifile >> ch; if(ch<0) ch=-ch; ch = ch % 10; ch='0' + ch; str[i]=ch; } ofstream ofile("/tmp/random"); ofile << str << endl; sleep(5); } }
下面是一个脚本,名字是myrandservice,放在/etc/init.d文件夹下:
#!/bin/sh # # chkconfig: 2345 80 50 # description: myrandservice is for testing how to write service in Linux # # processname: myrandservice # # Source function library. . /etc/rc.d/init.d/functions ret=0 start() { # check fdb status echo "start myrandservice" daemon /root/bin/myrand & ret=$? } stop() { echo "stop myrandservice" kill -9 $(ps -ef | grep myrand | grep -v grep | awk '{print $2}') ret=$? } status() { local result echo "check status of myrandservice..." #lines=$( ps -ef | grep myrand | grep -v grep | ) #echo $lines result=$( ps -ef | grep myrand | grep -v myrandservice | grep -v grep | wc -l ) #echo $result if [ $result -gt 0 ] ; then echo "my randservice is up" ret=0 else echo "my randservice is down" ret=1 fi echo "check status of myrandservice...done." } # See how we were called. case "$1" in start) start ;; stop) stop ;; status) status ;; *) echo {1}quot;Usage: $0 {start|stop|status}" exit 1 esac exit $ret
例子的一些说明
例子中脚本的下面两行既是给chkconfig用的。其中2345代表此服务在RunLevel2, 3, 4, 5下开启;80代表启动优先级;50代表结束优先级。如果RunLevel处不添值,用“-”代替,则代表此服务在任何runlevel下都不会自动启动,需要手动启动。可以通过service
<service-name> start/stop/status等来控制或查询Service。
# chkconfig: 2345 80 50
# description: myrandservice is for testing how to write service in Linux
脚本中的daemon函数存在于/etc/rc.d/init.d/functions中。daemon会重定向输出到/dev/null,也会设置是否生成coredump文件。通过daemon启动的程序,即使用户退出了命令行shell,也会保证Service会运行而不会退出。在/etc/rc.d/init.d/functions中还包括其他一些有用的函数,如killproc,status等,分别用来杀掉服务和查看服务状态。
相关文章推荐
- [转] Linux下编写脚本实现Daemon
- Linux 下用脚shell脚本实现进度条的编写
- [置顶] 编写shell脚本以及利用函数实现批量安装Linux服务配置
- 使用Python编写一个在Linux下实现截图分享的脚本的教程
- linux环境下编写shell脚本实现启动停止tomcat服务的方法
- linux编写两个脚本实现安全删除和恢复命令
- Linux下编写执行.sh脚本
- linux下进度条的编写和实现
- 转载]Linux 编写shell脚本(2)if for while
- 一个shell脚本实现linux集群所有机器免密钥登录
- Linux下使用daemon函数编写后台程序
- Linux 下通过脚本实现远程自动备份
- Linux 脚本编写基础
- Linux 脚本编写基础
- Linux通过脚本实现远程自动备份
- Linux使用expect脚本实现远程机器自动登录
- Linux下一个简单守护进程的实现 (Daemon)
- linux 用expect脚本实现scp服务器之间的文件备份
- Ackerman函数以及 Linux环境下的绘图(perl脚本实现)
- 编写脚本实现Zabbix监控Nginx状态