还需要考虑不同异常情况

helloworld.py

import datetime
import time
import osdef doSth():print('hello')n=os.system('./desktop/apache-tomcat-8.5.28/bin/startup.sh')print('thats all')time.sleep(60)def main(h=10,m=52):while True:while True:now = datetime.datetime.now()print(now)if now.hour == h and now.minute == m:breaktime.sleep(20)doSth()if __name__ == '__main__' :main()

运行时

nohup python helloworld.py &

&的意思是在后台运行,什么意思呢? 意思是说,当你在运行py的时候, 即使你用ctrl C,  那么helloworld.py照样运行(因为对 SIGINT信号免疫)。但是要注意,如果你直接关掉shell后,那么,helloworld.py进程同样消失。因为&对SIGHUP信号不免疫。

nohup的意思是忽略SIGHUP信号, 所以当运行nohup的时候, 关闭shell, 那么helloworld.py进程还是存在的(对SIGHUP信号免疫)。但是,要注意,如果你直接在shell中用Ctrl C, 那么, helloworld.py进程也是会消失的(因为对SIGINT信号不免疫)。

所以, &和nohup没有半毛钱的关系, 要让进程真正不受shell中Ctrl C和shell关闭的影响, 那该怎么办呢? 那就都用吧,两全其美。

nohup 和 &颇有点让helloworld.py成为守护进程的感觉。

但如果helloworld.py自身挂了怎么办呢,这个时候我们就考虑到monit

monit最大的特点是配置文件简单易读,同时支持进程和系统状态的监控,并灵活的提供了各种检测的方式,周期,并进行报警和响应(重启服务,执行命令等)

安装monit:

yum -y install monit

启动monit服务:

systemctl start monit.service

下面主要看monit配置文件和监控进程hang住并处理的脚本:

配置文件storaged.conf

[general]
time_interval = 5
storage_port = 9092
client_conf_file = /etc/fdfs/client.conf
[notice]
isemail = 1
issms = 1
ishotchat = 1
noticeusers= niuliguo
### Logging configuration
[loggers]
keys=root
[handlers]
keys=file_handler
[formatters]
keys=formatter
[logger_root]
level=DEBUG
handlers=file_handler
[handler_file_handler]
class=FileHandler
level=DEBUG
formatter=formatter
args=('/var/log/fdfs_storaged_protector.logs','a+')
[formatter_formatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s

脚本fdfs_storaged_protector.py

import os
import sys
import logging
import logging.handlers
import logging.config
import httplib
import json
import urllib
import socket
import time
import fcntl
from random import randint
from subprocess import PIPE,Popen
from signal import alarm,signal,SIGALRM,SIGKILL
from ConfigParser import ConfigParser
reload(sys)
sys.setdefaultencoding('utf-8')
__rootdir = os.path.realpath( os.path.dirname(__file__) )
if __rootdir not in sys.path:sys.path.append(__rootdir)
class Protector(object):def __init__(self,conf_path,rootdir):self.conf_general = 'general'self.conf_notice = 'notice'self.rootdir = rootdirself.ipaddr = socket.gethostbyname( socket.gethostname() )config_parser = ConfigParser()if config_parser.read(conf_path):self.time_interval = int( config_parser.get(self.conf_general,'time_interval','30') )self.storage_port = int( config_parser.get(self.conf_general,'storage_port','9092') )self.client_conf_file = config_parser.get(self.conf_general,'client_conf_file','/etc/fdfs/client.conf')self.isemail = config_parser.get(self.conf_notice,'isemail','1')self.issms = config_parser.get(self.conf_notice,'issms','1')self.ishotchat = config_parser.get(self.conf_notice,'ishotchat','1')self.noticeusers = config_parser.get(self.conf_notice,'noticeusers','niuliguo')logging.config.fileConfig(conf_path)self.logger = logging.getLogger('fdfs_storaged_protector')def handler(self,signum,frame):raise IOError("Timeout!")def run(self,args,cwd=None,shell=False,kill_tree=True,timeout=-1,env=None):  ''' Run a command in timeout,If out of time,process will be killed. '''  class Alarm(Exception):  pass  def alarm_handler(signum,frame):  raise Alarm  p = Popen(args,shell = shell,cwd = cwd,stdout = PIPE,stderr = PIPE,env=env)  if timeout != -1:  signal(SIGALRM,alarm_handler)  alarm(timeout)  try:  stdout,stderr = p.communicate()  if timeout != -1:  alarm(0)  except Alarm:  pids = [p.pid]  if kill_tree:  pids.extend(self.get_process_children(p.pid))  for pid in pids:  try:  os.kill(pid,SIGALRM)  except OSError:  pass  return -9,'',''  return p.returncode,stdout,stderr  def get_process_children(self,pid):p = Popen('ps --no-headers -o pid --ppid %d' % pid ,shell= True,stdout=PIPE,stderr = PIPE)stdout,stderr = p.communicate()return [ int(p) for p in stdout.split() ]def generate_small_file(self):try:with open( "%s/smallfile" % (self.rootdir),"wb") as fout:fout.write(os.urandom( 1024 * randint(80,180)) )if os.path.exists(os.sep.join([self.rootdir,"smallfile"])):self.logger.info("generate small file success")else:self.generate_small_file()except IOError:self.logger('generate small file fail!')def upload(self):if os.path.exists(os.sep.join([self.rootdir,"smallfile"])):cmd = 'fdfs_upload_file %s %s %s:%d > /dev/null' % (self.client_conf_file , os.sep.join([self.rootdir,"smallfile"]) , self.ipaddr , self.storage_port )return self.run(cmd,shell=True,timeout=10)else:self.logger.error("file %s not exist" % os.sep.join([self.rootdir,"smallfile"]))return -1,"","file missed"def monit(self):while True:retcode,stdout,stderr = self.upload()if 0 == retcode:self.logger.info("upload file success and the fdfs process is healthy")time.sleep(self.time_interval)elif stderr == "file missed":self.logger.error(stderr)self.generate_small_file()else:self.logger.error(stderr)breakdef restart_process(self):'''1.kill the fdfs_storaged process2.try to restart fdfs_storaged process for three times'''try:###step one: kill process cmd = 'ps -ef | grep \'/usr/bin/fdfs_storaged\'| grep -v grep | awk \'{print $2}\' | xargs kill -9'retcode,stdout,stderr = self.run(cmd,shell=True,timeout=10)###step two: restart processflag = Falsefor i in range(0,3):cmd = "systemctl stop fdfs_storaged.service && systemctl start fdfs_storaged.service"retcode,stdout,stderr = self.run(cmd,shell=True,timeout=10)if 0 == retcode:flag = Truebreakif flag:self.logger.info("restart fdfs_storaged success!")else:self.logger.info("restart fdfs_storaged fail!")except:self.logger.error("restart fdfs_storaged fail!")exit(1)def alarm(self):'''insert your own alarm code'''def restart_self(self):cmd = 'sh run.sh'retcode,stdout,stderr = self.run(cmd,shell=True,timeout=10)if 0 == retcode:self.logger.info("restart fdfs_storaged_protector process success")else:self.logger.error("restart fdfs_storaged_protector process fail")
if __name__ == '__main__':conf_path = os.sep.join([__rootdir,"storaged.conf"])protector = Protector(conf_path,__rootdir)try:protector.generate_small_file()protector.monit()raise Exceptionexcept Exception:protector.restart_process()protector.alarm()protector.restart_self()except KeyboardInterrupt:exit(1)except IOError:exit(1)

出处来自于https://blog.csdn.net/lavorange/article/details/51721330

牛哥小tips:1、ps aux | grep xxx的|是管道的意思,要专业

2、hang住是进程阻塞的意思,=block

3、写方法传参数进来时要判断参数是否为空,不然可能会全崩

第一篇博客——Python如何实现一个守护进程来定时每天在十点的时候跑shell脚本相关推荐

  1. 成就小我,从第一篇博客开始

    自我介绍 你们好,这是我的第一篇博客,一起见证一个菜鸟的成长吧.作为一名物联网专业的大二学生,即将面临大三找实习的压力,前路的未知更让我感到压抑.之前一直想写博客,但由于时间关系,或是更多由于自己的惰 ...

  2. Python 用pygame 做一个游戏的开始界面(小白第一篇博客)

    Python 用pygame 做一个游戏的开始界面(小白第一篇博客) 主要功能实现 本篇文章主要是实现了一个游戏开始界面的两个功能: 1,将鼠标放到"开始游戏"或"结束游 ...

  3. 我的第一篇博客:Python爬取新浪财经股票页面 并用matplotlib可视化输出结果

    (由于疫情在家闲着,开学至少得等到四月份,便在上个星期动起了学习python的念头,凭借着大一C语言微薄的基础草草学习语法后便开始了学写爬虫.跟着教学视频爬了几个静态网站后便开始尝试爬动态网站,同时也 ...

  4. Python中的TCP的客户端UDP学习----第一篇博客

    Python中的TCP的客户端&UDP学习--第一篇博客 PS: 每日的怼人句子"我真想把我的脑子放到你的身体里,让你感受一下智慧的光芒" 先说UDP流程 发送: 创建套接 ...

  5. 4. 写第一篇博客,最好的时间是今日,今时,今刻

    橡皮擦,一个逗趣的互联网高级网虫,为你带来新职场故事,搬来程序员敲门砖. 已完成文章 国内,首套,成体系,技术博客写作专栏发布啦 技术博客只能写技术文章吗?当然是由我们自己来定义. 为"她& ...

  6. 【个人随笔】我的第一篇博客(为什么、写什么、怎么写)

    关于这个博客(Ezrealer) 旧平台.新博客 这是我在这个博客下的第一篇博客,却是我使用CSDN的第N篇博客了,之所以又开了个博客,是想统一一下域名和ID,万一以后打造个个人品牌之类的,可以说是强 ...

  7. 决策树经典算法ID3——我的第一篇博客

    简介 决策树是机器学习中一种常见的分类算法,属于有监督学习算法(至于什么是有监督学习,什么是无监督学习读者可以自行百度).决策树算法有多种,ID3算法是其中一种经典的决策树算法,这种算法的核心是信息熵 ...

  8. 接第一篇博客:fw的第二场CTF——HECTF2021 WP

    第一篇博客,第一次参加比赛https://blog.csdn.net/qq_42880719/article/details/110139040就是HECTF 所以这HECTF我非打不可了 想当年,刚 ...

  9. 蒟蒻的第一篇博客CF1041C Coffee Break(二分+贪心+set)

    CF1041C Coffee Break(二分+贪心+set) 描述 Recently Monocarp got a job. His working day lasts exactly mm min ...

最新文章

  1. 安装varish作为缓存和代理
  2. 干货 | 45张图庖丁解牛18种Queue,你知道几种?
  3. pthread_cond_wait()加一个while为什么的解释
  4. 关于 sql server 基本使用的建议
  5. 【AI2】app inventor2离线开发环境百度网盘下载链接,安卓app图形化开发环境
  6. 收藏:DPDK内存基本概念
  7. SQL Server:SQL Like 通配符特殊用法:Escape
  8. LeetCode:位运算实现加法
  9. vue-cli3.0(创建项目)如何引入element-ui(指令篇)
  10. java利用栈求复杂表达式_java中的栈Stack的基本使用和应用(二) ——利用栈计算合法的算术表达,中缀表达式转后缀表达式...
  11. 详解IOS开发应用之并发Dispatch Queues
  12. Android PreferenceScreen介绍
  13. 网络安全----身份认证
  14. adb命令自动旋转屏幕
  15. 服务器和交换机物理连接_什么是光纤交换机?有什么功能?
  16. Python爬虫QQ空间好友说说
  17. cisco设备上查SFP模块sn
  18. linux wifi音箱,基于Orangpi Zero和Linux ALSA实现WIFI无线音箱(一)
  19. 如何修改PDF文件,PDF怎么插入图片
  20. WLAN 无线局域网 基本概念

热门文章

  1. 重磅!12306最新消息,官方购票日历已发布,最新春运消息尽在文中
  2. GitHub上的开源复刻:暗黑破坏神2
  3. 使用正向/逆向/双向三种算法进行分词操作
  4. 运动健康者的福音,拍照即可获取食物卡路里和营养元素啦
  5. QT-全键盘支持中英文
  6. 什么专业可以通过培训快速进入IC行业
  7. 移动互联网,是破坏性创新吗?
  8. 漏洞扫描工具OpenVAS安装与使用
  9. 服务器开关接线位置,你要找的家庭电路控制电路实物接线图、开关控制电路都在这里了!...
  10. 登录页获取短信验证码 读取短信验证码到键盘