发个在linux下用python写守护进程的好东东(转)

 一个别人写的模块,可以直接用来把一个普通进程改为守护进程。
并且自动把标准输出重定向到日志文件,很实用啊。

  1. <BR>   
  2. '''''<BR>  
  3.     This module is used to fork the current process into a daemon.<BR>  
  4.     Almost none of this is necessary (or advisable) if your daemon <BR>  
  5.     is being started by inetd. In that case, stdin, stdout and stderr are <BR>  
  6.     all set up for you to refer to the network connection, and the fork()s <BR>  
  7.     and session manipulation should not be done (to avoid confusing inetd). <BR>  
  8.     Only the chdir() and umask() steps remain as useful.<BR>  
  9.     References:<BR>  
  10.         UNIX Programming FAQ<BR>  
  11.             1.7 How do I get my program to act like a daemon?<BR>  
  12.                 [url]http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16[/url]<BR>  
  13.         Advanced Programming in the Unix Environment<BR>  
  14.             W. Richard Stevens, 1992, Addison-Wesley, ISBN 0-201-56317-7.<BR>  
  15. <BR>  
  16.     History:<BR>  
  17.       2001/07/10 by Juergen Hermann<BR>  
  18.       2002/08/28 by Noah Spurrier<BR>  
  19.       2003/02/24 by Clark Evans<BR>  
  20.       2003/11/01 by Irmen de Jong --- adapted a bit for Snakelets<BR>  
  21.                                     (raises exception at certain points)<BR>  
  22.       <BR>  
  23.       [url]http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66012[/url]<BR>  
  24. '''<BR>   
  25. import sys, os, time<BR>   
  26. from signal import SIGINT,SIGTERM,SIGKILL<BR>   
  27. <BR>   
  28. def daemonize(stdout='/dev/null', stderr=None, stdin='/dev/null',<BR>   
  29.               pidfile=None, startmsg = 'started with pid %s' ):<BR>   
  30.     '''''<BR>  
  31.         This forks the current process into a daemon.<BR>  
  32.         The stdin, stdout, and stderr arguments are file names that<BR>  
  33.         will be opened and be used to replace the standard file descriptors<BR>  
  34.         in sys.stdin, sys.stdout, and sys.stderr.<BR>  
  35.         These arguments are optional and default to /dev/null.<BR>  
  36.         Note that stderr is opened unbuffered, so<BR>  
  37.         if it shares a file with stdout then interleaved output<BR>  
  38.         may not appear in the order that you expect.<BR>  
  39.     '''<BR>   
  40. <BR>   
  41.     # flush io<BR>   
  42.     sys.stdout.flush()<BR>   
  43.     sys.stderr.flush()<BR>   
  44. <BR>   
  45.     # Do first fork.<BR>   
  46.     try: <BR>   
  47.         pid = os.fork() <BR>   
  48.         if pid > 0: sys.exit(0# Exit first parent.<BR>   
  49.     except OSError, e: <BR>   
  50.         sys.stderr.write("fork #1 failed: (%d) %s/n" % (e.errno, e.strerror))<BR>   
  51.         sys.exit(1)<BR>   
  52.         <BR>   
  53.     # Decouple from parent environment.<BR>   
  54.     os.chdir("/") <BR>   
  55.     os.umask(0) <BR>   
  56.     os.setsid() <BR>   
  57.     <BR>   
  58.     # Do second fork.<BR>   
  59.     try: <BR>   
  60.         pid = os.fork() <BR>   
  61.         if pid > 0: sys.exit(0# Exit second parent.<BR>   
  62.     except OSError, e: <BR>   
  63.         sys.stderr.write("fork #2 failed: (%d) %s/n" % (e.errno, e.strerror))<BR>   
  64.         sys.exit(1)<BR>   
  65.     <BR>   
  66.     # Open file descriptors and print start message<BR>   
  67.     if not stderr: stderr = stdout<BR>   
  68.     si = file(stdin, 'r')<BR>   
  69.     so = file(stdout, 'a+') <BR>   
  70.     se = file(stderr, 'a+'0)  #unbuffered<BR>   
  71.     pid = str(os.getpid())<BR>   
  72.     sys.stderr.write("/n%s/n" % startmsg % pid)<BR>   
  73.     sys.stderr.flush()<BR>   
  74.     if pidfile: file(pidfile,'w+').write("%s/n" % pid)<BR>   
  75.     <BR>   
  76.     # Redirect standard file descriptors.<BR>   
  77.     os.dup2(si.fileno(), sys.stdin.fileno())<BR>   
  78.     os.dup2(so.fileno(), sys.stdout.fileno())<BR>   
  79.     os.dup2(se.fileno(), sys.stderr.fileno())<BR>   
  80. <BR>   
  81. <BR>   
  82. class DaemonizeError(Exception): pass<BR>   
  83. <BR>   
  84. <BR>   
  85. def startstop(stdout='/dev/null', stderr=None, stdin='/dev/null',<BR>   
  86.               pidfile='pid.txt', startmsg = 'started with pid %s', action=None ):<BR>   
  87.               <BR>   
  88.     if not action and len(sys.argv) > 1:<BR>   
  89.         action = sys.argv[1]<BR>   
  90. <BR>   
  91.     if action:<BR>   
  92.         try:<BR>   
  93.             pf  = file(pidfile,'r')<BR>   
  94.             pid = int(pf.read().strip())<BR>   
  95.             pf.close()<BR>   
  96.         except IOError:<BR>   
  97.             pid = None<BR>   
  98.         if 'stop' == action or 'restart' == action:<BR>   
  99.             if not pid:<BR>   
  100.                 mess = "Could not stop, pid file '%s' missing./n"<BR>   
  101.                 raise DaemonizeError(mess % pidfile)<BR>   
  102.             try:<BR>   
  103.                while 1:<BR>   
  104.                    print "sending SIGINT to",pid<BR>   
  105.                    os.kill(pid,SIGINT)<BR>   
  106.                    time.sleep(2)<BR>   
  107.                    print "sending SIGTERM to",pid<BR>   
  108.                    os.kill(pid,SIGTERM)<BR>   
  109.                    time.sleep(2)<BR>   
  110.                    print "sending SIGKILL to",pid<BR>   
  111.                    os.kill(pid,SIGKILL)<BR>   
  112.                    time.sleep(1)<BR>   
  113.             except OSError, err:<BR>   
  114.                print "process has been terminated."<BR>   
  115.                os.remove(pidfile)<BR>   
  116.                if 'stop' == action:<BR>   
  117.                    return    ## sys.exit(0)<BR>   
  118.                action = 'start'<BR>   
  119.                pid = None<BR>   
  120.         if 'start' == action:<BR>   
  121.             if pid:<BR>   
  122.                 mess = "Start aborted since pid file '%s' exists. Server still running?/n"<BR>   
  123.                 raise DaemonizeError(mess % pidfile)<BR>   
  124.             daemonize(stdout,stderr,stdin,pidfile,startmsg)<BR>   
  125.             return<BR>   
  126.     print "usage: %s start|stop|restart" % sys.argv[0]<BR>   
  127.     raise DaemonizeError("invalid command")<BR>   
  128. <BR>   
  129. def test():<BR>   
  130.     '''''<BR>  
  131.         This is an example main function run by the daemon.<BR>  
  132.         This prints a count and timestamp once per second.<BR>  
  133.     '''<BR>   
  134.     sys.stdout.write ('Message to stdout...')<BR>   
  135.     sys.stderr.write ('Message to stderr...')<BR>   
  136.     c = 0<BR>   
  137.     while 1:<BR>   
  138.         sys.stdout.write ('%d: %s/n' % (c, time.ctime(time.time())) )<BR>   
  139.         sys.stdout.flush()<BR>   
  140.         c = c + 1<BR>   
  141.         time.sleep(1)<BR>   
  142. <BR>   
  143. if __name__ == "__main__":<BR>   
  144.     startstop(stdout='/tmp/daemonize.log',<BR>   
  145.               pidfile='/tmp/daemonize.pid')<BR>   
  146.     if sys.argv[1]in ('start''restart'):<BR>   
  147.         test()<BR>  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值