您可以*/30
在分钟说明符中输入-表示每分钟,但以30为步长(换句话说,每半小时)。由于cron
没有细分为分钟的解决方案,因此您需要寻找另一种方法。
一种可能性(虽然有点不合时宜(a))是有两项工作,一项抵消了30秒:
# Need these to run on 30-sec boundaries, keep commands in sync.
* * * * * /path/to/executable param1 param2
* * * * * ( sleep 30 ; /path/to/executable param1 param2 )
您会看到我添加了注释并对其进行了格式设置,以确保易于同步。
这两个cron
作业实际上每分钟运行一次,但是后一个作业将等待半分钟后再执行该作业的“工作” /path/to/executable
。
对于其他(非cron
基于)选项,请参见此处的其他答案,尤其是提及fcron
和的答案systemd
。假设您的系统具有使用它们的能力(例如,安装fcron
或其中有发行版systemd
),则这些选项可能是更可取的。
如果你不希望使用缺憾的解决方案,你可以使用一个小的修改环路为基础的解决方案。您仍然必须设法使您的进程以某种形式运行,但是,排序之后,以下脚本应该可以工作:
#!/bin/env bash
# Debug code to start on minute boundary and to
# gradually increase maximum payload duration to
# see what happens when the payload exceeds 30 seconds.
((maxtime = 20))
while [[ "$(date +%S)" != "00" ]]; do true; done
while true; do
# Start a background timer BEFORE the payload runs.
sleep 30 &
# Execute the payload, some random duration up to the limit.
# Extra blank line if excess payload.
((delay = RANDOM % maxtime + 1))
((maxtime += 1))
echo "$(date) Sleeping for ${delay} seconds (max ${maxtime})."
[[ ${delay} -gt 30 ]] && echo
sleep ${delay}
# Wait for timer to finish before next cycle.
wait
done
诀窍是在有效负载运行之前,使用一个sleep 30
but在后台启动它。然后,在完成有效负载后,只需等待后台sleep
完成。
如果有效负载需要n
几秒钟(其中n <= 30
),则有效负载之后的等待时间将是30 - n
几秒钟。如果花费的时间超过30秒,则下一个周期将被延迟,直到有效载荷完成为止,但不再。
您会看到我在那里有调试代码,开始时只有一分钟的时间,以便使输出最初更容易理解。我还逐渐增加了最大有效负载时间,因此您最终会看到有效负载超过了30秒的循环时间(输出了额外的空白行,因此效果很明显)。
随后进行示例运行(其中周期通常在上一个周期后30秒开始):
Tue May 26 20:56:00 AWST 2020 Sleeping for 9 seconds (max 21).
Tue May 26 20:56:30 AWST 2020 Sleeping for 19 seconds (max 22).
Tue May 26 20:57:00 AWST 2020 Sleeping for 9 seconds (max 23).
Tue May 26 20:57:30 AWST 2020 Sleeping for 7 seconds (max 24).
Tue May 26 20:58:00 AWST 2020 Sleeping for 2 seconds (max 25).
Tue May 26 20:58:30 AWST 2020 Sleeping for 8 seconds (max 26).
Tue May 26 20:59:00 AWST 2020 Sleeping for 20 seconds (max 27).
Tue May 26 20:59:30 AWST 2020 Sleeping for 25 seconds (max 28).
Tue May 26 21:00:00 AWST 2020 Sleeping for 5 seconds (max 29).
Tue May 26 21:00:30 AWST 2020 Sleeping for 6 seconds (max 30).
Tue May 26 21:01:00 AWST 2020 Sleeping for 27 seconds (max 31).
Tue May 26 21:01:30 AWST 2020 Sleeping for 25 seconds (max 32).
Tue May 26 21:02:00 AWST 2020 Sleeping for 15 seconds (max 33).
Tue May 26 21:02:30 AWST 2020 Sleeping for 10 seconds (max 34).
Tue May 26 21:03:00 AWST 2020 Sleeping for 5 seconds (max 35).
Tue May 26 21:03:30 AWST 2020 Sleeping for 35 seconds (max 36).
Tue May 26 21:04:05 AWST 2020 Sleeping for 2 seconds (max 37).
Tue May 26 21:04:35 AWST 2020 Sleeping for 20 seconds (max 38).
Tue May 26 21:05:05 AWST 2020 Sleeping for 22 seconds (max 39).
Tue May 26 21:05:35 AWST 2020 Sleeping for 18 seconds (max 40).
Tue May 26 21:06:05 AWST 2020 Sleeping for 33 seconds (max 41).
Tue May 26 21:06:38 AWST 2020 Sleeping for 31 seconds (max 42).
Tue May 26 21:07:09 AWST 2020 Sleeping for 6 seconds (max 43).
如果您要避免使用繁琐的解决方案,则可能会更好。您仍然需要一项cron
工作(或同等工作)来定期检测此脚本是否正在运行,如果没有运行,请启动它。但是脚本本身然后处理时间。
(a)我的一些同事会说,鞭打是我的专长:-)