问:
我有一个 python 脚本,它将检查队列并对每个元素执行操作:
# checkqueue.py
while true:
check_queue()
do_something()
如何编写 bash 脚本来检查它是否正在运行,如果没有,请启动它。 大致如下:伪**(或者它应该做类似 ps |。grep的事情? )
# keepalivescript.sh
if processidfile exists:
if processid is running:
exit, all ok
run checkqueue.py
write processid to processidfile
我将从 crontab 调用它
# crontab
5 * /path/to/keepalivescript.sh
一个:避免使用 pid 文件、cron 或任何其他试图评估不属于其子进程的进程。
在 Unix 中,等待子进程是有充分理由的。 任何试图解决这个问题的方法(ps 解析、pgrep、存储 pid 等)都是有缺陷的,并且存在漏洞。 稍后分析。
假设您的进程名为 proca,进程监控名为 procb,您需要 procb 作为 proca 的父进程。 因为只有启动流程的流程才能可靠地等待它结束。 这在 bash 中很容易实现。
until proca; do
echo "proca crashed with exit code $?restart..." >&2
sleep 1
done
上面的 bash 在 until 循环中运行 proca。 第一行开始 proca 并等待它结束。 当它结束时,直到检查其退出状态。 如果退出状态为 0,则表示它正常结束(这意味着您要求它以某种方式关闭,并且它成功关闭)。 在这种情况下,我们不想重新启动它(我们只是要求它关闭! 如果退出状态不是 0,则循环体将运行,这会在 stderr 上发出错误消息,并在 1 秒后重新启动循环(返回第 1 行)。
我们为什么要等一会儿? 因为如果 Proca 的启动顺序出现问题并立即崩溃,您将获得一个非常密集的不断重启和崩溃的循环。 睡眠 1 消除了这种压力。
然后需要做的就是启动这个 bash 脚本,它将监控 proca 并在必要时重新启动它。 如果你想在引导时启动监控脚本(操作系统),你可以用@reboot规则在用户的 cron(1) 中调度它。 使用 crontab -e 命令打开 cron 规则并添加规则以启动监视脚本:
@reboot /usr/local/bin/procamonitor
至于不使用pid文件的原因:
1.PID 重用(这可能导致杀死错误的进程)。
2.PID 文件已过时。 您需要过于复杂的逻辑来检查 pid 文件是否过时,并且任何此类逻辑在 1 中都存在相同的缺陷。
3.如果您甚至没有写入权限或处于只读环境中,该怎么办?
或者,查看 systemdunit(5)。您可以将名为 proca. 的文件添加到 lib systemd 系统目录服务,让 systemd 进程监控您的 proca。
[unit]
description=daemon for proca.
service]
execstart=/path/to/proca
restart=on-failure
restartsec=1s
install]
wantedby=multi-user.target
然后执行以下命令:
systemctl daemon-reload
systemctl enable proca.service
参考:stackoverflow 问题 696839
man systemd.unit
man systemctl
相关阅读:SH 和 Bash 的区别。
2>&1 在 shell 中是什么意思。
在 bash 中,是否更推荐使用双括号而不是单方括号。
如何检查是否在 bash 中设置了变量。