写一个脚本模拟监控推送组件,假设每分钟将ok的状态写入文件一次,并且以守护进程方式运行; apscheduler是一个定时任务模块
#!/bin/env python3
#-*- coding: utf-8 -*-
import os
import sys
import atexit
import time
from apscheduler.schedulers.blocking import BlockingScheduler
def daemonize(pid_file=None):
# 判断程序是否已经启动(不是必要的)
if pid_file is None:
pid_file = os.path.join("/tmp", ".".join((os.path.basename(__file__).split(".")[0], "pid")))
if os.path.isfile(pid_file):
print("%s 文件已存在" % pid_file)
sys.exit(100)
# 第一次fork
pid = os.fork()
if pid:
sys.exit(0)
# 子进程默认继承父进程的工作目录,最好是变更到根目录,否则回影响文件系统的卸载
os.chdir('/')
# 子进程默认继承父进程的umask(文件权限掩码),重设为0(完全控制),以免影响程序读写文件
os.umask(0)
# 让子进程成为新的会话组长和进程组长
os.setsid()
_pid = os.fork()
if _pid:
sys.exit(0)
# 刷新缓冲区
sys.stdout.flush()
sys.stderr.flush()
# dup2函数原子化地关闭和复制文件描述符,重定向到/dev/nul,即丢弃所有输入输出
with open('/dev/null') as read_null, open('/dev/null', 'w') as write_null:
os.dup2(read_null.fileno(), sys.stdin.fileno())
os.dup2(write_null.fileno(), sys.stdout.fileno())
os.dup2(write_null.fileno(), sys.stderr.fileno())
# 写入pid文件
with open(pid_file, 'w') as f:
f.write(str(os.getpid()))
# 注册退出函数,进程退出时移除pid文件
atexit.register(os.remove, pid_file)
def proc():
os.popen("echo 'ok' >> /tmp/file")
if __name__ == "__main__":
daemonize()
sched = BlockingScheduler()
sched.add_job(proc, "interval", seconds=60)
sched.start()