是否可以将 cron 脚本设置为每 5 分钟运行一次?
我有两个脚本,脚本 1 从一个数据库收集一些数据并将其插入另一个数据库,脚本 2 提取这些数据和大量其他数据并从中创建一些漂亮的报告。这两个脚本都需要每 5 分钟运行一次。我想将脚本 2 偏移一分钟,以便它可以根据新数据创建报告。例如,我希望脚本 1 每小时运行一次,:00, :05, :10, :15 [...]
脚本 2 每小时运行一次:01, :06, :11, :16 [...]
。这两个脚本彼此不依赖,无论脚本 1 是否成功,脚本 2 都必须运行。但如果报告可以包含最新数据,那将很有用。使用 cron 可以做到这一点吗?
发布;
我曾考虑在 shell 脚本中使用这两个命令,以便它们立即运行,但这样做行不通,有时脚本 1 可能会因等待外部 API 等而挂起。因此可能需要长达 15 分钟才能运行,但脚本 2 必须每 5 分钟运行一次,因此这样做会停止/延迟脚本 2 的执行。如果我可以在 Cron 中设置它,这意味着无论脚本 1 正在做什么,脚本 2 都会运行
答案1
你可以使用 随时运行脚本cron
。如果你想每 5 分钟运行一次脚本 1,你可以这样开始:
*/5 * * * * /path/to/script1
但这实际上只是以下简写:
0,5,10,15,20,25,30,35,40,45,50,55 * * * * /path/to/script1
如果要在脚本 1 运行一分钟后运行脚本 2,可以这样做:
1,6,11,16,21,26,31,36,41,46,51,56 * * * * /path/to/script2
你也可以这样做:
*/5 * * * * /path/to/script1
*/5 * * * * /path/to/script2
然后在脚本 2 开始时,睡眠一分钟:
sleep 60
答案2
crontab 的分钟输入字段接受“增量”运算符,这有点令人困惑,因为它看起来应该是数学上的“除以”运算符,但实际上不是。您最常看到它使用如下形式。请注意,这不会查找可被五整除的数字,而是从集合中取出每五项:
*/5 * * * * command
/5
这将告诉 cron从分钟集 0-59 ( ) 中匹配每第五个项目 ( *
),但您可以像这样更改该集合:
1-59/5 * * * * command
这将从集合 1-59 中取出每五个项目,并在第 6、11、16 分钟等处运行您的命令。
如果您需要比一分钟更细粒度的偏移量,您可以使用 sleep 命令作为 crontab 的一部分来进行破解,如下所示:
*/5 * * * * sleep 15 && command
这将每五分钟运行一次您的作业,但命令实际上要到该分钟后的 15 秒才会启动。对于运行时间较短的作业,晚几秒会产生很大的影响,但您又不想晚一分钟,这是一个非常简单的技巧。
答案3
您可以使用 + 符号指示时间偏移。例如,要在 运行:01, :06, :11, :16 [...]
,请创建一个任务,例如
*/5+1 * * * * command
答案4
这是一XY问题. 将 cron 与整小时间隔或其常见分数相抵消通常可以减少重合过程,但这个问题明确指出偏移是为了解决依赖关系。虽然我们被告知无论脚本 1 是否完成,脚本 2 都必须运行,但它绝对不应该在脚本 1 正在更新共享数据集时尝试运行。仅使用时间来强制执行序列,在最好的情况下会在两者之间造成不必要的延迟,在最坏的情况下会造成竞争条件。
最好将它们放入同一个 cron 作业行中以创建时间顺序依赖关系:
*/5 * * * * /path/to/script1; /path/to/script2
分号分隔命令但确保所有命令都将运行,无论之前的退出状态如何。
如果仅当第一个命令成功时才应运行第二个命令,请将其更改为:
*/5 * * * * /path/to/script1 && /path/to/script2
我认为这是后者的情况,如果报告是根据旧数据生成的,则不会更改,如果报告是根据不完整的数据生成的,则完全错误,那么为什么要在第一个脚本成功运行之前创建另一个报告呢?要么重新发送上一个报告的缓存副本,要么根本不发送。如果第一个脚本有可能运行时间超过 cron 间隔,则应使用基本锁定(例如使用flock
)以确保不会有并发运行向同一位置发出竞争请求。