我正在寻找一个简单而通用的解决方案,允许您在 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
而且仍然非常简单。