我正在尝试设置一个cron job作为我创建的守护进程的看门狗。如果守护进程出错并失败,我希望cron job周期性地重新启动它...我不确定这是否可行,但我阅读了几篇cron教程,没有找到任何能做我所需功能的内容...
我的守护进程是从shell脚本启动的,所以我只是想找到一种方式,只有在上一个作业运行完毕后才能运行cron job。
我发现了这篇文章,它提供了使用锁文件来实现我想做的事情的解决方案,但我不确定是否有更好的方法来完成这项工作...
使用flock
。它是新的。它更好。
现在你不必亲自编写代码。在这里查看更多原因:https://serverfault.com/a/82863
/usr/bin/flock -n /tmp/my.lockfile /usr/local/bin/my_script
我为自己编写的打印池程序这样做,它只是一个Shell脚本:
#!/bin/sh
if ps -ef | grep -v grep | grep doctype.php ; then
exit 0
else
/home/user/bin/doctype.php >> /home/user/bin/spooler.log &
#mailing program
/home/user/bin/simplemail.php "Print spooler was not running... Restarted."
exit 0
fi
它每两分钟运行一次,非常有效。如果由于某种原因该过程未运行,我会通过电子邮件接收特殊信息。
grep [d]octype.php
而不是 grep -v grep | grep doctype.php
。 - AlexT&
。 - lainatnavigrep
就会进行唯一的搜索。一个小的改进可能是在最右边的 grep
上添加 --quiet
选项。 - undefined正如其他人所说,编写和检查PID文件是一个不错的解决方案。这是我的bash实现:
#!/bin/bash
mkdir -p "$HOME/tmp"
PIDFILE="$HOME/tmp/myprogram.pid"
if [ -e "${PIDFILE}" ] && (ps -u $(whoami) -opid= |
grep -P "^\s*$(cat ${PIDFILE})$" &> /dev/null); then
echo "Already running."
exit 99
fi
/path/to/myprogram > $HOME/tmp/myprogram.log &
echo $! > "${PIDFILE}"
chmod 644 "${PIDFILE}"
”和“
>>`”。对此感到抱歉。 - rsanden[ -e "${PIDFILE}" ]
")。如果不存在,则会在后台启动程序,将其 PID 写入文件("echo $! > "${PIDFILE}"
"),然后退出。如果 PID 文件存在,则脚本将检查您自己的进程("ps -u $(whoami) -opid=
")并查看是否正在运行具有相同 PID 的进程("grep -P "^\s*$(cat ${PIDFILE})$"
")。如果没有运行,则会像之前一样开始程序,用新的 PID 覆盖 PID 文件,然后退出。我认为没有修改脚本的必要,你觉得呢? - rsanden不要尝试通过cron来执行此操作。让cron无论如何都运行一个脚本,然后由脚本决定程序是否正在运行,并在必要时启动它(请注意,您可以使用Ruby或Python或您喜欢的脚本语言来完成此操作)。
当我运行php脚本时,我的做法是:
* * * * * php /path/to/php/script.php &
<?php
if (shell_exec('ps aux | grep ' . __FILE__ . ' | wc -l') > 1) {
exit('already running...');
}
// do stuff
你也可以在crontab中直接使用一行命令:
* * * * * [ `ps -ef|grep -v grep|grep <command>` -eq 0 ] && <command>
ps -ef|grep [c]ommand
-eq 0 ] && <command>[ "$(ps -ef|grep [c]ommand|wc -l)" -eq 0 ] && <command>
- thameera[ $(grep something | wc -l) -eq 0 ]
是一个非常绕弯子的写法,其实可以用! grep -q something
来代替。因此,你只需要使用ps -ef | grep '[c]ommand' || command
就可以了。 - tripleee# one instance only (works unless your cmd has 'grep' in it)
ALREADY_RUNNING_EXIT_STATUS=0
bn=`basename $0`
proc=`ps -ef | grep -v grep | grep "$bn" | grep -v " $$ "`
[ $? -eq 0 ] && {
pid=`echo $proc | awk '{print $2}'`
echo "$bn already running with pid $pid"
exit $ALREADY_RUNNING_EXIT_STATUS
}
使用flock的更好方法进行更新:
/usr/bin/flock -n /tmp/your-app.lock /path/your-app args
setlock
、s6-setlock
、chpst
和runlock
在它们的非阻塞模式下是可用于不只是Linux的替代工具。 - JdeBP