防止重复运行 cron 作业

防止重复运行 cron 作业

我已安排一个 cron 作业每分钟运行一次,但有时脚本需要一分钟以上的时间才能完成,我不希望作业开始“堆积”在一起。我猜这是一个并发问题 - 即脚本执行需要相互排斥。

为了解决这个问题,我让脚本寻找特定文件的存在(“锁文件.txt“) 并且如果存在则退出,touch如果不存在则退出。但这是一个非常糟糕的信号量!是否有我应该知道的最佳实践?我应该编写一个守护进程吗?

答案1

有几个程序可以自动执行此功能,消除了自己执行此操作带来的烦恼和潜在错误,并且通过在后台使用 flock 也避免了陈旧的锁定问题(如果您只使用 touch,则存在风险)。我过去曾使用过lockrun和,但现在有(1)(在较新版本的 util-linux 中),它很棒。它真的很容易使用:lckdoflock

* * * * * /usr/bin/flock -n /tmp/fcj.lockfile /usr/local/bin/frequent_cron_job

答案2

在 shell 中最好的方法是使用羊群(1)

(
  flock -x -w 5 99
  ## Do your stuff here
) 99>/path/to/my.lock

答案3

实际上,flock -n可以代替lckdo*,因此您将使用来自内核开发人员的代码。

构建于沃姆布尔的例子,你可以这样写:

* * * * * flock -n /some/lockfile command_to_run_every_minute

顺便说一句,查看代码,、flocklockrunlckdo做同样的事情,所以这只是一个最容易获得的问题。

答案4

您尚未指定是否希望脚本等待上一次运行完成。通过“我不希望作业开始‘堆叠’在一起”,我猜您的意思是如果脚本已经在运行,则希望脚本退出,

因此,如果您不想依赖 lckdo 或类似的东西,您可以这样做:


PIDFILE=/tmp/`basename $0`.pid

if [ -f $PIDFILE ]; then
  if ps -p `cat $PIDFILE` > /dev/null 2>&1; then
      echo "$0 already running!"
      exit
  fi
fi
echo $$ > $PIDFILE

trap 'rm -f "$PIDFILE" >/dev/null 2>&1' EXIT HUP KILL INT QUIT TERM

# do the work

相关内容