你好,我目前正在尝试设置一个 bash 脚本,在 2 个单独的屏幕中启动 5 个 python 进程,然后检查我的 python 脚本当前是否正在运行,如果没有则重新启动它们。总共有 5 个 python 脚本。 4 个脚本在 1 个屏幕中运行,1 个脚本在另一个屏幕中运行。我是 Linux 和脚本新手,所以我希望我只是犯了一个小错误。我目前只是想把它们全部杀死,然后在屏幕上重新启动它们(如果它们中的任何一个停止了)。这是我的 bash 脚本:
#!/bin/bash
screen -dm -S "screen1" python script1.py
screen -dm -S "screen2" python script2.py & python script3.py & python script4.py & python script5.py
while true; do
num_procs=$(pgrep -lf python | wc -l)
if [ "$num_procs" != "7" ]; then
pkill python
screen -dm -S "fail" python script_failed.py
sleep 10
pkill python
screen -dm -S "screen1" python script1.py
screen -dm -S "screen2" python script2.py & python script3.py & python script4.py & python script5.py
fi
sleep 20
done
如果我的代码失败,我还希望收到通知,以便我可以追溯其失败原因,这就是我启动 script_failed.py 的原因,因为它会向我发送一封失败的电子邮件。我使用 num_procs = 7 因为有 5 个 python 进程和 2 个屏幕。由于某种原因,屏幕也计入 num_procs。正如您在 pgrep -af python 的输出中看到的那样:
1146 SCREEN -dm -S screen1 python scrip1.py
1148 python script1.py
1154 python script3.py
1155 python script4.py
1156 python script5.py
1157 SCREEN -dm -S screen2 python script2.py
1158 python script2.py
我尝试在该位置周围使用回声来查看代码到达和卡住的位置,但在完成最初启动屏幕后,我发现回声甚至不起作用。另外,如果我只杀死了 1 个 python 脚本,那么 while 循环似乎不起作用,但如果我杀死所有脚本,它就会工作并重新启动。在我杀死所有进程之前,回声和 while 循环是否会在分离的屏幕或其他东西中丢失?我还注意到 pkill 有时不会杀死 python 进程。
任何帮助,将不胜感激。谢谢。
答案1
我可能会做下面概述的事情。这将为每个屏幕实例创建一个单独的看门狗脚本,因此您不必完全重新启动屏幕实例,并且通过使用 .pid 文件可以更准确地验证脚本是否仍在运行。
编辑每个 python 脚本 (1-5) 以创建 .pid 文件(示例:https://stackoverflow.com/a/789383/5670331)
编辑主脚本:
#!/bin/bash
screen -dm -S "screen1" watchdog1.sh
screen -dm -S "screen2" watchdog2.sh
看门狗1.sh
while true; do
sleep 10
ps up `cat /tmp/python_script_1.pid` >/dev/null && echo "Script 1 is running" || python script1.py &
done
看门狗2.sh
while true; do
sleep 10
ps up `cat /tmp/python_script_2.pid` >/dev/null && echo "Script 2 is running" || python script2.py &
ps up `cat /tmp/python_script_3.pid` >/dev/null && echo "Script 3 is running" || python script3.py &
ps up `cat /tmp/python_script_4.pid` >/dev/null && echo "Script 4 is running" || python script4.py &
ps up `cat /tmp/python_script_5.pid` >/dev/null && echo "Script 5 is running" || python script5.py &
done