防止长时间 cron 作业并行运行的通用解决方案?

防止长时间 cron 作业并行运行的通用解决方案?

我正在寻找一个简单而通用的解决方案,允许您在 crontab 中执行任何脚本或应用程序并防止其运行两次。

解决方案应该独立于执行的命令。

我认为它看起来应该像lock && (command ; unlock)如果有另一个锁,锁将返回 false。

第二部分就像是获得了锁,运行命令,并在命令执行后解锁,即使它返回错误。

答案1

看一下这个run-one包。从命令手册run-one手册页图标

运行一次是一个包装脚本,它使用一组独特的参数运行某个命令的不超过一个独特实例。

当您希望一次运行不超过一个副本时,这对于 cronjobs 非常有用。

就像time或一样sudo,你只需将其添加到命令前面即可。因此,cronjob 可能如下所示:

  */60 * * * *   run-one rsync -azP $HOME example.com:/srv/backup

如需了解更多信息和背景信息,请查看介绍它的博客文章作者:达斯汀·柯克兰(Dustin Kirkland)。

答案2

设置锁的一个非常简单的方法:

if mkdir /var/lock/mylock; then
  echo "Locking succeeded" >&2
else
  echo "Lock failed - exit" >&2
  exit 1
fi

想要运行的脚本需要创建锁。如果锁存在,则另一个脚本正忙,因此第一个脚本无法运行。如果文件不存在,则没有脚本获取锁。因此当前脚本获取锁。当脚本完成后,需要通过移除锁来释放锁。

有关 bash 锁的更多信息,请查看

答案3

不需要安装一些花哨的包:

#!/bin/bash
pgrep -xf "$*" > /dev/null || "$@"

自己编写该脚本比运行“apt-get install”更快,不是吗?您可能希望将“-u $(id -u)”添加到 pgrep 以仅检查当前用户运行的实例。

答案4

您需要一把锁。run-one可以完成这项工作,但您可能还想查看一下flock包装util-linux

它是内核开发人员提供的标准包,允许更多定制,run-one而且仍然非常简单。

相关内容