zoukankan      html  css  js  c++  java
  • [转] Linux下编写脚本实现Daemon

    Linux(以Redhat Linux Enterprise Edition 5.3为例)下,有时需要编写ServiceService也是程序,一般随系统启动用户不干预就不退出的程序,可以称为ServiceLinux下的Service一般称为Daemon

     

    以上是广义的Service的定义。Linux下的服务一般放在/etc/init.d文件夹下。浏览一下这个文件夹下的文件,可以发现在Linux下编写Service一般遵循的原则。

     

    Linux下编写Service一般遵循的原则

    1)真正运行的Service一般放在某个bin目录下(/bin/usr/binetc)。

    2/etc/init.d文件夹下一般是shell脚本,用来控制bin目录下的Service

    3/etc/init.d文件夹下的shell脚本一般接受至少两个参数,startstop。还有其他常用的可选参数如statusreloadrestart,等。

    4/etc/init.d文件夹下的shell脚本至少包括两行注释,一行告诉chkconfig此服务运行的runlevel,启动优先级,结束优先级。一行告诉chkconfig此服务的描述。

     

    Linux的启动过程和RunLevel

    要理解Linux的启动过程和RunLevel,可以先浏览一下/etc/inittab文件。在/etc/inittab中定义了下面7RunLevel。每个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。如下,代表缺省RunLevel5

     

    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文件夹下,会发现以SK开头的脚本的链接,SK后面还带2位数字。其中S代表StartK代表KillS开头的脚本,在rc中调用的时候会带start参数;K开头的脚本,在rc中调用的时候会带stop参数。SK后面带的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

    1. /* myrand.cpp 
    2.  * this program read 4 chars from /dev/random in each iteration, 
    3.  * and then adjust it to 0-9. Finally the 4 chars are written 
    4.  * to /tmp/random. This is only for testing /dev/random, and 
    5.  * at the same time serve as a example service. 
    6.  */  
    7. #include <iostream>  
    8. #include <fstream>  
    9. using namespace std;  
    10. #include <unistd.h>  
    11.    
    12.    
    13. int main()  
    14. {  
    15.                 while (true)  
    16.                 {  
    17.                                 ifstream ifile("/dev/random");  
    18.                                 char ch;  
    19.                                 char str[5];  
    20.                                 str[4]=0;  
    21.                                 int i;  
    22.                                 for(i=0;i<4;i++)  
    23.                                 {  
    24.                                                 ifile >> ch;  
    25.                                                 if(ch<0) ch=-ch;  
    26.                                                 ch = ch % 10;  
    27.                                                 ch='0' + ch;  
    28.                                                 str[i]=ch;  
    29.                                 }  
    30.    
    31.                                 ofstream ofile("/tmp/random");  
    32.                                 ofile << str << endl;  
    33.                                 sleep(5);  
    34.                 }  
    35. }  


    下面是一个脚本,名字是myrandservice,放在/etc/init.d文件夹下:

     

    [plain] view plaincopy
    1. #!/bin/sh  
    2. #  
    3. # chkconfig: 2345  80 50  
    4. # description: myrandservice is for testing how to write service in Linux  
    5. #               
    6. # processname: myrandservice  
    7. #  
    8. # Source function library.  
    9. . /etc/rc.d/init.d/functions  
    10.    
    11.    
    12. ret=0  
    13.    
    14.    
    15. start() {  
    16.     # check fdb status  
    17.                 echo "start myrandservice"  
    18.                 daemon /root/bin/myrand &  
    19.                 ret=$?  
    20. }  
    21.    
    22. stop() {  
    23.     echo "stop myrandservice"  
    24.                 kill -9 $(ps -ef | grep myrand | grep -v grep | awk '{print $2}')  
    25.                 ret=$?  
    26. }  
    27.    
    28. status() {  
    29.                 local result  
    30.                 echo "check status of myrandservice..."  
    31.                 #lines=$( ps -ef | grep myrand | grep -v grep  |  )  
    32.                 #echo $lines  
    33.                 result=$( ps -ef | grep myrand | grep -v myrandservice | grep -v grep | wc -l )  
    34.                 #echo $result  
    35.                 if [ $result -gt 0 ] ; then  
    36.                                 echo "my randservice is up"  
    37.                                 ret=0  
    38.                 else  
    39.                                 echo "my randservice is down"  
    40.                                 ret=1  
    41.                 fi  
    42.                 echo "check status of myrandservice...done."  
    43. }  
    44.    
    45. # See how we were called.  
    46. case "$1" in  
    47.   start)  
    48.         start  
    49.         ;;  
    50.   stop)  
    51.         stop  
    52.         ;;  
    53.   status)  
    54.                                 status  
    55.         ;;  
    56.   *)  
    57.         echo {1}quot;Usage: $0 {start|stop|status}"  
    58.         exit 1  
    59. esac  
    60.    
    61. exit $ret  

    例子的一些说明

    例子中脚本的下面两行既是给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中还包括其他一些有用的函数,如killprocstatus等,分别用来杀掉服务和查看服务状态。

     http://blog.csdn.net/tianhuadihuo/article/details/6647398

    附:另外一个script例子

    • Runlevel 0: Halt
    • Runlevel 1: Single user mode
    • Runlevel 6: Reboot
    #!/bin/bash
    #
    # chkconfig: 35 90 12
    # description: Foo server
    #
    # Get function from functions library
    . /etc/init.d/functions
    # Start the service FOO
    start() {
            initlog -c "echo -n Starting FOO server: "
            /path/to/FOO &
            ### Create the lock file ###
            touch /var/lock/subsys/FOO
            success $"FOO server startup"
            echo
    }
    # Restart the service FOO
    stop() {
            initlog -c "echo -n Stopping FOO server: "
            killproc FOO
            ### Now, delete the lock file ###
            rm -f /var/lock/subsys/FOO
            echo
    }
    ### main logic ###
    case "$1" in
      start)
            start
            ;;
      stop)
            stop
            ;;
      status)
            status FOO
            ;;
      restart|reload|condrestart)
            stop
            start
            ;;
      *)
            echo $"Usage: $0 {start|stop|restart|reload|status}"
            exit 1
    esac
    exit 0
  • 相关阅读:
    Redis命令行之Hash
    Redis命令行之String
    Redis配置
    访问者模式【行为模式】
    状态模式【行为模式】
    责任链模式【行为模式】
    观察者模式【行为模式】
    策略模式【行为模式】
    模板方法模式【行为模式】
    组合模式【结构模式】
  • 原文地址:https://www.cnblogs.com/moher/p/3263601.html
Copyright © 2011-2022 走看看