当上一次运行未完成时,如何阻止 cron 作业。这是一项 cron 作业,每 5 分钟运行一次,但有时需要超过 5 分钟才能运行。
编辑 调用的脚本有时会崩溃!所以它无法删除锁定文件。
答案1
使用flock(1)
:
NAME
flock - manage locks from shell scripts
SYNOPSIS
flock [options] <file> -c <command>
flock [options] <directory> -c <command>
flock [options] <file descriptor number>
[...]
您可以让它阻塞或立即退出。锁定文件是否存在没有影响。它会在需要时创建文件并使用系统flock()
调用锁定文件。此锁定会在进程死亡时自动释放。
例如,在 cron 中:
*/5 * * * * /usr/bin/flock /tmp/my.lock /usr/local/bin/myjob
如果您的工作并不总是在 5 分钟内完成,您可以考虑使用,--timeout
这样您的工作就不会排队:
flock --timeout=300
或者使用--nonblock
立即退出——它类似于--timeout=0
如果你的脚本是一个 shell 脚本,你可以使用一些巧妙的重定向技巧在脚本本身中使用 flock:
(
flock -n 9 || exit 1
# ... commands executed under lock ...
) 9>/var/lock/mylockfile
或者,手册还建议通过将其放在顶部使脚本递归(它使用脚本本身作为其锁文件):
[ "${FLOCKER}" != "$0" ] && exec env FLOCKER="$0" flock -en "$0" "$0" "$@" || :
请参阅flock(1)
手册页以了解更多信息
答案2
然而,Pid 文件是可行的方法,就像 init 脚本在看到 pid 文件时不会放弃一样,您应该检查以确保文件中的 pid 仍然存在。
像这样的事情就可以解决问题:
PIDFILE=/var/run/myscript.pid
if [ -e "$PIDFILE" ] ; then
# our pidfile exists, let's make sure the process is still running though
PID=`/bin/cat "$PIDFILE"`
if /bin/kill -0 "$PID" > /dev/null 2>&1 ; then
# indeed it is, i'm outta here!
/bin/echo 'The script is still running, forget it!'
exit 0
fi
fi
# create or update the pidfile
/bin/echo "$$" > $PIDFILE
... do stuff ...
/bin/rm -f "$PIDFILE"
答案3
当 cron 作业在退出后无法清理文件时,检查 pid 或 lock 文件可能会失败。我认为更好的选择是检查进程本身,例如:
ps -ef | grep script_name | grep -v grep | wc -l
这将为您提供名称为“script_name”的进程数。您可以在脚本执行开始时检查此计数。
答案4
例如,在 中查找文件/var/run
。如果找到该文件,则退出。否则,创建该文件,运行例程,然后删除该文件。