python脚本基本写法
import os, time, sys f = open('/home/hikari/MonitTest/pid/mypython.pid', 'w') f.writelines(str(os.getpid())) f.close() for i in range(1,99999): print ("Hello World!") time.sleep(1) ~ import sys, os, time, s
ignal mypid = 0 mypath = "/home/hikari/Learn/pid/mypython.pid" if len(sys.argv) >1 : if sys.argv[1] == "start": f = open(mypath,'w') mypid = os.getpid() print (mypid) f.write(str(mypid)) f.close() for i in range(1,100000): print("Hello World") time.sleep(2) if sys.argv[1] == "stop": if os.path.exists(mypath): f = open(mypath,'r') mypid = int(f.read()) f.close() os.kill(mypid,signal.SIGKILL) os.remove(mypath)
shell 脚本
PIDFILE=/var/run/scraper.pid case $1 in start) source /home # Launch your program as a detached process python /home/scraper.py 2>/dev/null & # Get its PID and store it echo $! > ${PIDFILE} ;; stop) kill `cat ${PIDFILE}` # Now that it's killed, don't forget to remove the PID file rm ${PIDFILE} ;; *) echo "usage: scraper {start|stop}" ;; esac exit 0
总结出来的一个稳定版本
monit 控制文件
check process shellXpython matching "/home/hikari/Learn/python/test.sh" start program = "/home/hikari/Learn/python/test.sh" stop program = "/home/hikari/Learn/sh/kill.sh"
tesh.sh
{ #在shell内新建一个后台进程 python /home/hikari/Learn/python/test.py start } & #正常退出 exit 0
kill.sh
#!/bin/sh pidfile=/home/hikari/Learn/pid/mypy.pid kill `cat ${pidfile}` exit 0
test.py
负责模拟一个长期运行的后台进程
import sys, os, time, signal mypid = 0 mypath = "/home/hikari/Learn/pid/mypy.pid" if len(sys.argv) >1 : if sys.argv[1] == "start": f = open(mypath,'w') mypid = os.getpid() print(mypid) f.write(str(mypid)) f.close() for i in range(1,10000): print(i) time.sleep(2) if sys.argv[1] == "stop": if os.path.exists(mypath): f = open(mypath,'r') mypid = int(f.read()) f.close() os.kill(mypid,signal.SIGKILL) os.remove(mypath) time.sleep(99)
改进-myscript.sh
将test.sh 和 kill.sh 合并,通过输入不同参数决定调用对象。
PIDFILE=/var/run/myscript.pid case $1 in start) source /home # Launch your program as a detached process python /home/hikari/Learn/python/test.py start 2>/dev/null & # 2>/dev/null 的含义是把标准错误输出到/dev/null文件中 # Get its PID and store it echo $! > ${PIDFILE} ;; stop) kill `cat ${PIDFILE}` # Now that it's killed, don't forget to remove the PID file rm ${PIDFILE} ;; *) echo "usage: myscript {start|stop}" ;; esac exit 0
关于program 与process的选择
在选择check服务时,process和program代表两种不同的程序。
process代表长时间工作的后台进程,在check process服务中可以接pidfile或matching,而matching可以选择文件路径。process中不能使用status。
program代表短时间内可以执行结束的程序或脚本,status只能与program配对。其原因是status是隔一段指定时间检测程序的退出值,根据退出值采取不同行动。而process要长期运行,故status属性不适用process。
program必须是短时间内可以结束的,否则一段时间后检测不到退出值,将报Execute Failed错误。原因就是程序没有结束,status检测不到程序退出值,以为程序执行失败。
据此,要在program内执行长进程要采用并发进程。假设并发进程为A,令program进程调用并发进程A & 后,立即退出,就可以达到需求。在A后面加&的效果是使A在后台运行。
至此program在短时间内得到了退出值,而长进程A也可以继续执行。