运行多个 cron 作业,其中一项作业需要很长时间

use*_*015 18 cron

我有以下关于 cron 工作的一般问题。

假设我有以下内容crontab

* 10 * * * * someScript.sh
* 11 * * * * someScript2.sh
30 11 */2 * * someScript3.sh  <-- Takes a long time let's say 36 hours.
* 12 * * * someScript4.sh
Run Code Online (Sandbox Code Playgroud)

在适当的时间运行剩余的作业是否足够聪明?例如,长脚本不需要终止?

另外,如果最初的长脚本仍在运行并且它再次被 cron 调用会发生什么?

谢谢!

sou*_*ake 33

每个 cron 作业的执行都独立于您可能指定的任何其他作业。这意味着您的长期脚本不会阻止其他作业在指定时间执行。

如果您的任何脚本仍在其下一个计划的 cron 间隔执行,则将执行脚本的另一个并发实例。

这可能会产生无法预料的后果,具体取决于您的脚本的作用。我建议阅读维基百科关于文件锁定的文章,特别是关于锁定文件的部分。锁定文件是一种简单的机制,用于表示资源(在您的情况下是someScript3.sh脚本)当前被“锁定”(即正在使用)并且在锁定文件被删除之前不应再次执行。

有关在脚本中实现锁定文件的方法的详细信息,请查看以下问题的答案:


Bra*_*ram 8

不确定您所说的适当时间是什么意思。Cron 将在它计划的时间开始作业。它不会检查其他计划作业或作业的其他实例。

因此,您定义的任何有效作业都将在定义的时间启动。任何运行时间超过定义间隔的作业都将启动多次。如果需要,编写作业的人有责任阻止它实际运行多次。通过例如检查锁定文件或 PID 文件或其他东西。

可以并行运行的进程数量有明显的限制,但这些限制不是特定于 cron 的。


Edh*_*dil 6

除了其他答案,尤其是@soulcake 发布的链接:如果您安排一个长时间运行的命令间隔太短,cron 会在第一个完成之前愉快地执行第二个(除非在命令中实现了某种互斥锁) .

这通常会进一步减慢原始命令的速度,导致在前一个命令完成之前运行另一个实例,等等。或者由于其他原因可能是不受欢迎的。

防止的一般方法是使用保护条件运行命令,以确保前一个命令没有运行。例如:

10 * * * * pgrep my_slow_command >/dev/null || /usr/local/bin/my_slow_command
Run Code Online (Sandbox Code Playgroud)

确保 pgrep 在运行时匹配命令的名称,例如,python 脚本将 python 作为可执行文件的名称,这可能不够具体,您还必须匹配 python 的脚本名称。

10 * * * * pgrep -f my_script.py || /usr/local/bin/my_script.py
Run Code Online (Sandbox Code Playgroud)

(不过,没有 '-f' 选项的 pgrep 匹配 bash 脚本名称)

如果由于某种原因不能使用 pgrep:

10 * * * * ps ax | grep [m]y_command || /usr/local/bin/my_command
Run Code Online (Sandbox Code Playgroud)

括号用于避免匹配 grep 命令本身。