下一次运行的剩余时间

Key*_*ate 11 cron timestamps

我需要在我的 Cron 计划中计算下一次运行特定作业的剩余时间,我有一个 Cron,其作业频率为每小时、一天三次等,没有在特定日期/日期运行的作业,因此只是 HH: MM:SS 担心,我也没有权利检查/var/spool/cron/我的 RHEL。如果某个工作开始于9:30

30 9 * * * /some/job.sh
-bash-3.2$ 日期 +"%H:%M"
13:52

我需要输出,19 Hours and 38 Minutes我如何知道从当前系统时间到下一次运行的总时间?秒的计算只关注工作时间。

Sté*_*las 11

cron不知道什么时候工作会被解雇。它所做的就是每分钟检查所有crontab条目并触发匹配的条目"$(date '+%M %H %d %m %w')"

您可以做的是从现在到 49 小时后每分钟生成所有这些时间戳(考虑 DST 更改),手动进行匹配(棘手的部分)并报告第一个匹配的。

或者你可以使用croniter python模块:

python -c '
from croniter import croniter
from datetime import datetime
iter = croniter("3 9 * * *", datetime.now())
print iter.get_next(datetime)'
Run Code Online (Sandbox Code Playgroud)

对于延迟:

$ faketime 13:52:00 python -c '
from croniter import croniter
from datetime import datetime
d = datetime.now()
iter = croniter("30 9 * * *", d)
print iter.get_next(datetime) - d'
19:37:59.413956
Run Code Online (Sandbox Code Playgroud)

不过要注意 DST 更改的潜在错误:

$ faketime '2015-03-28 01:01:00' python -c '
from croniter import croniter
from datetime import datetime
iter = croniter("1 1 * * *", datetime.now())
print iter.get_next(datetime)'
2015-03-29 02:01:00

$ FAKETIME_FMT=%s faketime -f 1445734799 date
Sun 25 Oct 01:59:59 BST 2015
$ FAKETIME_FMT=%s faketime -f 1445734799  python -c '
from croniter import croniter
from datetime import datetime
iter = croniter("1 1 * * *", datetime.now())
print iter.get_next(datetime)'
2015-10-25 01:01:00

$ FAKETIME_FMT=%s faketime -f 1445734799 python -c '
from croniter import croniter
from datetime import datetime
d = datetime.now()
iter = croniter("1 1 * * *", d)
print iter.get_next(datetime) - d'
-1 day, 23:01:01
Run Code Online (Sandbox Code Playgroud)

cron 它本身通过避免在时间倒退的情况下运行作业两次来解决这个问题,或者如果时间倒退,则避免在轮班后运行跳过的作业。

  • @Keys,您不必在 root 拥有的位置安装该模块(或 python)。所以你不必是root。 (2认同)

Sté*_*las 8

碰巧的是,shell 内置%T格式确实支持标准 crontab 规范作为输入。printfksh93

$ ksh93 -c 'printf "%(%F %T)T\n" now "30 9 * * *"'
2017-11-07 17:06:41
2017-11-08 09:30:00
Run Code Online (Sandbox Code Playgroud)

因此,您可以通过以下方式在几秒钟内获得增量:

#! /bin/ksh93 -
crontab_line='30 9 * * *'
delta=$(($(printf '(%(%s)T - %(%s)T) / 60' "$crontab_line" now)))
echo "Next run in $((delta/60)) hours and $((delta%60)) minutes."
Run Code Online (Sandbox Code Playgroud)

请注意,它不支持某些(大多数)cron 实现有时支持的扩展,例如*/5或 月/日名称或 7 作为星期几,或@reboot,@hourly等。