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)\n" % (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)\n" % (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\n" % 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?\n"
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?\n" % 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?\n" % 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!\n" % self.pidfile
print(message)
sys.stdout.write(message)
else:
message = "pidfile %s exist. But pid not exist, please administrator check process\n" % 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)
参考文档:
http://blog.csdn.net/taiyang1987912/article/details/44850999
http://python3-cookbook-zh.readthedocs.io/zh_CN/latest/c12/p14_launching_daemon_process_on_unix.html
python实现Linux启动守护进程的更多相关文章
- Yii2.0 安装yii2-queue并在Linux启动守护进程监听消息
一.什么是yii2-queue? Yii2-queue是Yii2.0 PHP框架下一个消息队列拓展插件,支持基于DB, Redis, RabbitMQ, AMQP, Beanstalk 和 Gearm ...
- linux 创建守护进程的相关知识
linux 创建守护进程的相关知识 http://www.114390.com/article/46410.htm linux 创建守护进程的相关知识,这篇文章主要介绍了linux 创建守护进程的相关 ...
- 【Linux】- 守护进程的启动方法
转自:Linux 守护进程的启动方法 Linux中"守护进程"(daemon)就是一直在后台运行的进程(daemon). 本文介绍如何将一个 Web 应用,启动为守护进程. 一.问 ...
- asp.net core2.0 部署centos7/linux系统 --守护进程supervisor(二)
原文:asp.net core2.0 部署centos7/linux系统 --守护进程supervisor(二) 续上一篇文章:asp.net core2.0 部署centos7/linux系统 -- ...
- linux C守护进程编写
linux编程-守护进程编写 守护进程(Daemon)是运行在后台的一种特殊进程.它独立于控制终端并且周期性地执行某种任务或等待 处理某些发生的事件.守护进程是一种很有用的进程. Linux的大多数服 ...
- python中的daemon守护进程实现方法
原文参考:http://blog.csdn.net/tao_627/article/details/49532021 守护进程是生存期长的一种进程.它们独立于控制终端并且周期性的执行某种任务或等待处理 ...
- hadoop启动守护进程报JAVA_HOME is not set and could not be found
hadoop启动守护进程 sbin/start-dfs.sh 报如下错误:JAVA_HOME is not set and could not be found 解决办法(JAVA_HOME修改为具体 ...
- Linux Supervisor 守护进程基本配置
supervisor:C/S架构的进程控制系统,可使用户在类UNIX系统中监控.管理进程.常用于管理与某个用户或项目相关的进程. 组成部分supervisord:服务守护进程supervisorctl ...
- Python与Hack之守护进程
1.什么是守护进程: 在linux或者unix操作系统中,守护进程(Daemon)是一种运行在后台的特殊进程,它独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件.由于在linux中,每个 ...
随机推荐
- Replace Pioneer注册
以下是目前合法长期使用Replace Pioneer的唯一方法(除了购买之外): Replace Pioneer过期后,会弹出一个注册(Registration)窗口,其中有一个试用选项(Trial ...
- WEB API 中HTTP的get、post、put,delete 请求方式
一.WEB API 中HTTP 请求方式的四个主要方法 (GET, PUT, POST, DELETE), 按照下列方式映射为 CURD 操作: 1.POST 用于新建资源,服务端在指定的URI 上创 ...
- Matlab绘图详解
Matlab绘图 强大的绘图功能是Matlab的特点之一,Matlab提供了一系列的绘图函数,用户不需要过多的考虑绘图的细节,只需要给出一些基本参数就能得到所需图形,这类函数称为高层绘图函数.此外,M ...
- Javascript/jQuery 获取地址栏URL参数的方法
1.jquery获取url很简单,代码如下 window.location.href; 2.javascript获取url参数 function getUrlParam(name) { var reg ...
- android开发------第一个android程序
好吧,现在我们就一起来写第一个android程序,看它带给了我们什么.sdk的使用和虚拟机的创建我就不说了.项目创建过程先略过,不太重要. 那第一个程序我们能学到什么知识呢?一起看吧.^-^ 在IDE ...
- Java微信公众号开发-外网映射工具配置
一.开发环境准备 1.一个微信公众号 2.外网映射工具(开发调试)如花生壳.ngrok工具 注:与微信对接的URL要具备以下条件a:在公网上能够访问 b:端口只支持80端口 这里使用ngrok.cc: ...
- 在Winform中播放视频等【DotNet,C#】
在项目中遇到过这样的问题,就是如何在Winform中播放视频.当时考察了几种方式,第一种是直接使用Windows Media Player组件,这种最简单:第二种是利用DirectX直接在窗体或者控件 ...
- iOS开发中的错误整理,iOS9之后的UIWindow(TopWindow)以及UIWindow与statusBar的关系
iOS9之后的UIWindow的问题(TopWindow),以及UIWindow与statusBar之间的联系 1.出现的问题 iOS9之后UIWindow必须要指定一个根控制器,不然会报错!iOS9 ...
- 51nod 1434 理解lcm
1434 区间LCM 题目来源: TopCoder 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 收藏 关注 一个整数序列S的LCM(最小公倍数)是指最小的正 ...
- C#-WinForm-对话框控件
对话框控件 设置点击按钮弹出对话框控件 1.colorDialog - 颜色对话框 接收确定返回的信息 ============================================ ...