有时您必须确保同一时间只有一个 shell 脚本实例正在运行。
例如,通过 crond 执行的 cron 作业本身不提供锁定(例如默认的 Solaris crond)。
实现锁定的常见模式是这样的代码:
#!/bin/sh
LOCK=/var/tmp/mylock
if [ -f $LOCK ]; then # 'test' -> race begin
echo Job is already running\!
exit 6
fi
touch $LOCK # 'set' -> race end
# do some work
rm $LOCK
Run Code Online (Sandbox Code Playgroud)
当然,这样的代码有竞争条件。有一个时间窗口,其中两个实例的执行都可以在第 3 行之后才能访问$LOCK
文件。
对于 cron 作业,这通常不是问题,因为两次调用之间有几分钟的间隔。
但是事情可能会出错——例如,当锁定文件在 NFS 服务器上时——挂起。在这种情况下,多个 cron 作业可以在第 3 行阻塞并排队。如果NFS服务器再次处于活动状态,那么你已经惊群并行运行的作业。
在网上搜索我发现工具lockrun似乎是该问题的一个很好的解决方案。使用它,您可以运行一个需要像这样锁定的脚本:
$ lockrun --lockfile=/var/tmp/mylock myscript.sh
Run Code Online (Sandbox Code Playgroud)
您可以将其放在包装器中或从您的 crontab 中使用它。
lockf()
如果可用,它使用(POSIX) 并回退到flock()
(BSD)。并且lockf()
对 NFS …
如果我有一个 crontab 作业,例如每小时运行一次,但该作业可能需要一个多小时才能完成,下一个作业是否会无法运行?
我正在寻找有关创建脚本的指导,该脚本将检查特定文件夹、打印所有文档(如果有)然后删除这些文档。我还想将此脚本作为 cron 作业运行。
我希望这样做的原因是因为我目前有一个 PHP 网络应用程序,它可以动态创建 pdf 发票并将它们保存在某个文件夹中,但我无法从网络自动打印这些文档(我想是为了安全/垃圾邮件问题)。
我没有语言偏好,但理想情况下希望脚本能够控制打印多少份,在打印机中使用哪个托盘等。