我们有较长的构建,通常我们会安排我们的 cron 作业,但有时我们必须在非标准时间范围内重新运行构建,并且可能会与通常在那些时间安全运行的 cron 作业发生冲突。
我们有多个运行构建和 cron 作业的帐户,因此我们无法暂停整个机器的 crontab 服务然后稍后重新启动它。
我想知道是否有人有模式或实现。我想象这就像
用户创建一个文件:~/block-crontab
用户运行构建 cron 作业在用户的主目录中查找该文件,如果存在,则跳过所有 cron 作业。否则,它将运行作业 然后,当构建完成时,用户将删除 ~/block-crontab
这样做有用吗?我猜我需要以某种方式修改 cron 脚本。我最想知道是否有更好/标准的方法来解决此问题?
谢谢。
答案1
我强烈建议您在构建脚本中实现某种(哪怕是简单的)锁定形式,而不是乱搞crond
。例如,触摸并检查 中的文件/var/run/
:如果您的脚本找到了某些内容,则另一个进程正在构建该项目。您显然需要在完成后删除锁定文件。
正如@GnP 在评论中指出的那样,您还可以使用该flock
实用程序半自动管理您的锁文件。
如果您不依赖/不能依赖任何锁定机制,只需发出service crond stop
即可关闭crond
系统。
答案2
我倾向于将所有长时间运行的命令包装在一个屏幕中,并且cron
只有当尚未运行时才启动该屏幕。
因此,以下行crontab
*/2 * * * * /bin/bash /path/to/LongRunningScript.bash
...变成了这样:
*/2 * * * * /usr/bin/screen -S MyUniqueName -Q select . || /usr/bin/screen -dmS MyUniqueName /bin/bash /path/to/LongRunningScript.bash
我喜欢这个,因为它还让你有机会附加到正在运行的脚本并检查其输出/状态。
在您的场景中,您可以cron
在执行构建之前检查另一个屏幕,例如
0 3 * * * /usr/bin/screen -S ManualBuild -Q select . || /usr/bin/screen -dmS AutomatedBuild /bin/bash /path/to/BuildScripts.bash
10 3 * * * /usr/bin/screen -S ManualBuild -Q select . || /usr/bin/screen -dmS OtherAutomatedBuild /bin/bash /path/to/OtherBuildScripts.bash
screen
当您运行手动构建时,在运行脚本之前,只需先跳转到(如果您需要提示如何连接/断开连接,请发表评论screen
。这是一个有用的实用程序 - 如果您还没有开始使用它,请尝试一下)
键入screen -S ManualBuild
、点击[enter]
并运行您想要运行的任何命令。
注意:如果您使用提供的示例,您可能cron
会对正在运行的多个名为“ManualBuild”的屏幕会话感到困惑。