我有一个守护程序,可以使用 GPIO 端口监视各种事物。我已经使用 python 使用 RPi.GPIO 模块为此编写了代码。
我想确保守护进程始终运行,即在崩溃后重新启动它并在系统启动时启动它(至关重要的是在任何用户登录之前 - 这个 Pi 无头运行)。有一个闪烁的 LED 灯告诉我它正在运行,但这并不理想。
我已经阅读过有关使用 MONIT 来实现此目的的信息,但我遇到了一些问题。到目前为止我的尝试主要围绕这个解决方案:
https://stackoverflow.com/questions/23454344/use-monit-monitor-a-python-program
这是我的 bash 包装文件,名为 /home/pi/UPSalarm/UPSalarm.bash
#!/bin/bash
PIDFILE=/var/run/UPSalarm.pid
case $1 in
start)
#source /home
#Launch script
sudo python /home/pi/UPSAlarm/UPSalarm.py 2>/dev/null &
# store PID value
echo $! > ${PIDFILE}
;;
stop)
kill `cat ${PIDFILE}`
# Proccess killed, now remove PID
rm ${PIDFILE}
;;
*)
echo "usage: scraper {start|stop}" ;;
esac
exit 0`
这是我的监控规则
check process UPSalarm with pidfile /var/run/UPSalarm.pid
start = "/home/pi/UPSalarm/UPSalarm start"
stop = "/home/pi/UPSalarm/UPSalarm stop"
我有两个问题:首先,我在 UPSalarm.pid 中得到了错误的 PID 号。我想知道我是否能获得 sudo 的 PID 号?这就是为什么我在这里发布这个问题;我需要 sudo 因为我需要访问 GPIO 端口。其次,它不起作用。第三,我不确定source
bash文件中的内容是什么?
我知道 monit 有很好的文档,但是 python 的有效示例确实会很有帮助,我已经被困了好几天了。
以下网站也很有帮助: https://www.the-hawkes.de/monitor-your-raspberrypi-with-monit.html(用于设置监视器) https://mmonit.com/monit/documentation/monit.html
这两个问题是相关的,但不能解决我的问题: https://raspberrypi.stackexchange.com/questions/9938/monitoring-a-python-script-running-in-a-screen-session-with-monit 如果 Python 脚本被杀死或死亡,如何自动重新启动它
答案1
该 shell 包装器看起来像一个 init 脚本,但显然它不是(因此您需要sudo
在那里使用;由 init 运行的脚本不需要这个)。
这似乎是一种非常笨拙的方法; shell 包装器没有任何 Python 程序本身无法更好地实现的目的。摆脱它;如果您特别想要一个 init 脚本,请编写一个最小的脚本,但我建议您将控制守护进程的逻辑从 init 脚本移至守护进程 ( UPSalarm.py
) 本身。
由于您只需要一个实例,因此请定义该进程要使用的 pid 文件。运行时UPSalarm.py start
,它将检查该文件是否存在。如果不存在,则将自己的pid写入该文件并继续。如果确实存在,它会获取 pid,然后检查操作系统以查看是否存在具有该 pid 的进程,如果存在,则该进程的名称是什么。这将证明要么UPSalarm.py
已经在运行,要么没有。如果是,则退出并显示“已运行”消息。
运行时UPSalarm.py stop
,涉及类似的序列 - 检查 pid 文件,如果存在,则检查 pid,如果 pid 对于名为 的进程有效UPSalarm.py
,则发出停止信号,可能使用SIGINT
. UPSalarm.py
本身应该实现一个信号处理程序SIGINT
,以便它在退出之前删除 pid 文件。
我不是 python 程序员,这也不是编程网站(为此,请参阅堆栈溢出),但我保证这一切都可以通过 python 轻松实现。
- 要获取当前进程的pid,使用
os.getpid()
。 - 要将 pid 映射到进程名称,请读取
/proc/[pid]/cmdline
并执行字符串搜索UPSalarm.py
(或者更好的是,调用的进程名称,这将是sys.argv[0]
,请参阅这里)。 - 对于信号处理,启动这里和这里。
- 要将信号发送到另一个进程,使用
os.kill()
。
然后应该很容易配置monit
来处理这个守护进程。然后,您还可以选择仅使用(或您自己的脚本)每隔一段时间(例如每 5-10 分钟)cron
调用一次。UPSalarm.py start