我有一个 shell 脚本,它只在循环中调用 Python 文件,例如:
for i in $(seq $start_index $end_index)
do
python my_script.py
done
当 Python 进程无法生成特定范围内的随机数时,它会停止。
当脚本在 30 秒内没有打印到控制台时,我尝试重新启动脚本,否则它可以继续运行。
这不是一个需要以固定时间间隔重新启动的 cron 作业。
然而,一种可以跟踪的看门狗工作将是理想的;但我没有找到任何跟踪最后一次输出打印时间的信息。
我们还可以直接输出script.sh > log.txt
并检查文件上次修改的时间,但没有找到一种优雅的方法来做到这一点。
任何帮助/指示将不胜感激。
答案1
正如我设法从OP中解释的那样:
- 您启动进程
my_script.py
,但无法预测终止或退出时间。 - 进程
my_script.py
执行并写入日志文件(调用它file.log
直到它停止。 - 每隔一个小时间间隔,您需要检查日志文件的最后修改时间是否早于 30 秒。如果是,则终止并重新启动进程
my_script.py
有多种方法可以做到这一点。其中之一是依靠inotify
包inotify-tools
来监视文件系统的事件,沿着完美的答案这里和(更好)那里。
上述方法的替代方法是手动检测日志文件的最后修改日期并检查进程的 pid 是否继续显示。将所有逻辑放在一个简短的可执行 bash 脚本中,如下所示:
#!/bin/bash
/usr/bin/python my_script.py >> file.log & # launch process in background
my_proc_pid="$!" # save process pid for last executed command
prevtime=0 # initialize "previous modification time" variable
while : ; do
sleep 1 # check log file modification time every 1s
# modification time in milliseconds
if (( $(\find /path/to/file.log/ -name file.log -printf "%T") - prevtime > 30000)); then
#if (( "$(\ls -l --time-style=+%s /path/to/logfile/file.log | cut -d' ' -f6)" - prevtime > 30)); then
prevtime="$(\find /path/to/file.log/ -name file.log -printf \"%T\")"
#prevtime="$(\ls -l --time-style=+%s /path/to/logfile/file.log | cut -d' ' -f6)"
if (\ps | grep -v grep | grep "$my_proc_pid" &>/dev/null) ; then
# kill process in background, '&>' same as '>/dev/null 2>&1'
/usr/bin/kill -9 "$my_proc_pid" &>/dev/null
fi
# launch process and save its pid
/usr/bin/python my_script.py >> file.log &
my_proc_pid="$!"
fi
done
# use CTRL-C to stop loop execution and to exit script
笔记:
我提供了两种查找日志文件修改时间的方法。没有注释掉的涉及到find
处理奇怪的文件名(例如带空格等)比ls
并且不依赖于任何管道更好。在这种情况下,您必须提供完整的小路到您的日志文件 ( /path/to/logfile/
) 作为 cmd 的第一个参数find
。在 的情况下ls
,您需要提供相同的路径以及完整日志文件的文件名,如下所示:/path/to/logfile/file.log
我在bash
v5.0.1 上对此进行了部分测试。如有问题请报告。华泰