Python实现Linux进程重启,python实现Linux启动守护进程

python实现Linux启动守护进程

DaemonClass.py代码:

#/usr/bin/env python

# -*- coding: utf-8 -*-

import sys

import os

import time

import atexit

import subprocess

from signal import SIGTERM

BaseDir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

DIRS = {'ROOT': BaseDir,

'PID': '%s/var/guard.pid' % BaseDir,

}

class Daemon(object):

"""

daemon class.

Usage: subclass the Daemon class and override the _run() method

"""

def __init__(self, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):

self.stdin = stdin

self.stdout = stdout

self.stderr = stderr

self.pidfile = DIRS['PID']

def _daemonize(self):

"""

@guard 守护进程主方法

"""

# 脱离父进程

try:

pid = os.fork()

print("[_daemonize]pid:%s" % pid)

if pid > 0:

sys.exit(0)

except OSError as e:

sys.stderr.write("[_daemonize]fork #1 failed: %d (%s)

" % (e.errno, e.strerror))

print("[_daemonize]fork #1 failed:"+str(e.strerror))

sys.exit(1)

# 脱离终端

os.setsid()

# 修改当前工作目录

os.chdir(DIRS['ROOT'])

# 加载环境变量

guardpath = DIRS['ROOT']

sys.path.append(guardpath)

# 重设文件创建权限

os.umask(0)

# 第二次fork,禁止进程重新打开控制终端

try:

pid = os.fork()

if pid > 0:

sys.exit(0)

except OSError as e:

sys.stderr.write("[_daemonize]fork #2 failed: %d (%s)

" % (e.errno, e.strerror))

print("[_daemonize]fork #2 failed:"+str(e.strerror))

sys.exit(1)

sys.stdout.flush()

sys.stderr.flush()

# 重定向文件描述符

with open(self.stdin, 'rb', 0) as f:

os.dup2(f.fileno(), sys.stdin.fileno())

with open(self.stdout, 'ab', 0) as f:

os.dup2(f.fileno(), sys.stdout.fileno())

with open(self.stderr, 'ab', 0) as f:

os.dup2(f.fileno(), sys.stderr.fileno())

# 注册程序退出时的函数,即删掉pid文件

atexit.register(lambda: os.remove(self.pidfile))

pid = str(os.getpid())

file(self.pidfile, 'w+').write("%s

" % pid)

def start(self):

"""

Start the daemon

"""

# Check for a pidfile to see if the daemon already runs

try:

with open(self.pidfile, 'r') as pf:

pid = int(pf.read().strip())

except IOError as e:

pid = None

print("daemon ioerror :"+str(e))

if pid:

message = "Start error,pidfile %s already exist. Daemon already running?

"

print(message)

sys.stderr.write(message % self.pidfile)

sys.exit(1)

# Start the daemon

self._daemonize()

self._run()

def stop(self):

"""

Stop the daemon

"""

# Get the pid from the pidfile

try:

with open(self.pidfile, 'r') as pf:

pid = int(pf.read().strip())

except IOError as err:

pid = None

print(err)

if not pid:

message = "pidfile %s does not exist. Daemon not running?

" % self.pidfile

print(message)

sys.stderr.write(message)

return # not an error in a restart

# Try killing the daemon process

try:

while 1:

os.kill(pid, SIGTERM)

time.sleep(0.1)

except OSError as err:

err = str(err)

if err.find("No such process") > 0:

if os.path.exists(self.pidfile):

os.remove(self.pidfile)

else:

print('Stop error,'+str(err))

sys.exit(1)

def status(self):

"""

Status the daemon

"""

# Get the pid from the pidfile

try:

with open(self.pidfile, 'r') as pf:

pid = int(pf.read().strip())

except IOError as err:

pid = None

print(err)

if not pid:

message = "pidfile %s does not exist. Daemon not running?

" % self.pidfile

print(message)

sys.stderr.write(message)

else:

p = subprocess.Popen('ps -ef|grep %s |grep -v grep' % pid, shell=True,

stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

lines = p.stdout.readlines()

print(lines)

if len(lines) > 0:

message = "pidfile %s exist. Daemon running!

" % self.pidfile

print(message)

sys.stdout.write(message)

else:

message = "pidfile %s exist. But pid not exist, please administrator check process

" % self.pidfile

print(message)

sys.stderr.write(message)

def restart(self):

"""

Restart the daemon

"""

self.stop()

time.sleep(0.1)

self.start()

def _run(self):

"""

You should override this method when you subclass Daemon. It will be called after the process has been

daemonized by start() or restart().

"""

raise NotImplementedError

MainClass.py 继承Daemon类

#/usr/bin/env python

# -*- coding: utf-8 -*-

import sys

from DaemonClass import *

import time

import subprocess

class ArgvHandler(Daemon):

"""

help_msg: 帮助方法

parse_argv: 参数检查

"""

def __init__(self, argv_list):

Daemon.__init__(self)

self.argvs = argv_list

print("程序输入参数:%s" % self.argvs)

self.parse_argv()

def parse_argv(self):

"""

:return: 获取执行程序后面的参数值,如果没有打印帮助内容

"""

if len(self.argvs) > 1:

if hasattr(self, self.argvs[1]):

func = getattr(self, self.argvs[1])

func()

else:

self.help_msg()

else:

self.help_msg()

def help_msg(self):

print "Unknow Command!"

print "Usage: %s start|stop|restart|status" % self.argvs[0]

def _run(self):

"""

监控入口

"""

MonitorRun()

def MonitorRun():

while 1:

monitor_process('进程名')

time.sleep(600)

def monitor_process(processname):

# 进程数量判断

try:

p = subprocess.Popen('ps -ef|grep %s |grep -v grep' % processname, shell=True,

stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

lines = p.stdout.readlines()

if len(lines) == 1:

print("进程名:%s, 数量:%s" % (processname, len(lines)))

return

else:

print("进程名:%s, 数量:%s" % (processname, len(lines)))

message = 'process[%s] is lost' % (processname)

print(message)

return message

except Exception as err:

message = "[monitor_process]%s" % err

print(message)

sys.stderr.write(message)

启动程序入口

#/usr/bin/env python

# -*- coding: utf-8 -*-

import os

import sys

import platform

if platform.system() == "Windows":

BASE_DIR = '\'.join(os.path.abspath(os.path.dirname(__file__)).split('\')[:-1])

else: # for linux

BASE_DIR = '/'.join(os.path.abspath(os.path.dirname(__file__)).split('/')[:-1])

sys.path.append(BASE_DIR)

from lib import MainClass

if __name__ == '__main__':

MainClass.ArgvHandler(sys.argv)

参考文档:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值