我的场景:
我在树莓派上有一些 python 脚本。它们的行为就像一项服务,它们永远运行而无需退出和处理信号。它们旨在在后台运行,将一些值写入 MariaDB。它们在无人看管的情况下运行,没有登录用户。
但是,有时它们会崩溃。我不知道为什么,对我来说似乎很难找出发生了什么(随机崩溃,没有模式,没有线索,有时它们会运行数月,有时它们每天都会崩溃)。
由于此脚本处理的信号并不重要,因此我只想:
- 编写一个shell脚本,杀死所有正在运行的python脚本并重新启动它们
- 每天使用 crontab 运行此脚本两次,因此如果发生崩溃,我不会丢失太多数据,也不必关心检查和重新启动它们
我已经编写了 shell 脚本“restart.sh”并在 bash 中执行它效果很好:
#!/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
kill $(pgrep python3)
sleep 2
nohup python3 script1.py &
sleep 2
nohup python3 script2.py &
sleep 2
nohup python3 script3.py &
sleep 2
exit
我还用 修改了我的 crontab sudo crontab -e
,其中包含:
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
0 9 * * * /home/pi/restart.sh
0 15 * * * /home/pi/restart.sh
我的问题:
测试 crontab,我可以看到它restart.sh
已执行,但只有第一个命令,即kill
命令,有效。所有正在运行的 python3 脚本都被杀死,但不会再次启动。
我尝试添加PATH
and SHELL
,因为这似乎是常见问题,但这并没有改变任何东西。
我也尝试先编辑crontab -e
没有sudo
,同样的问题。
我在这里想念什么?如果我在终端中手动运行,为什么nohup
命令不像它们那样执行?./restart.sh
我可以做些什么来让这个脚本开始使用 crontab?
使用 pkill 而不是 pgrep 可能更干净,但我认为这不是问题所在。
从您提供的信息中我不确定为什么您的脚本没有按预期工作(对我来说看起来不错)。
但是,我不确定在从 cron 命令调用的脚本中使用“&”是正确的做法。我的第一个替代建议是使用 cron 在后台本地运行的事实,并且每个 python 脚本都有一个单独的 cron 作业,而不是一次完成所有工作。
如果我理解正确,则症状是 python 程序完全崩溃而不是挂起,并且假设如果他们高兴,最好继续运行,您可以使用 start-if-not-running 脚本(我使用重击):
然后在你的 crontab 中:
解释:
ps -ef
搜索进程表的整个命令行(pgrep 和 pkill 默认只搜索前 13 个字符)$value -lt 2
表示如果少于两个匹配项,则继续并启动一个新脚本(总会有一个匹配项 - grep 命令本身的匹配项)我还强烈建议您确保您的树莓派通过电子邮件将 cron 命令的输出发送给您,如果您还没有进行设置(例如https://medium.com/swlh/setting-up-gmail-and-other- email-on-a-raspberry-pi-6f7e3ad3d0e)作为调试的帮助。