我需要计算 Cron 计划中下一次运行特定作业的剩余时间,我有一个 Cron,其作业频率为每小时、每天三次等,没有作业在特定日期/日期运行,因此只有 HH: MM:对于SS来说,我也无权检查/var/spool/cron/
我的RHEL。如果某项工作开始于9:30
,
30 9* * * /一些/job.sh -bash-3.2$ 日期 +"%H:%M" 13:52
我需要输出为,19 Hours and 38 Minutes
我如何知道从当前系统时间到下一次运行发生的总时间?秒数的计算仅涉及工作时间。
答案1
cron
不知道什么时候工作会被解雇。它所做的就是每分钟检查所有crontab
条目并解雇那些匹配的条目"$(date '+%M %H %d %m %w')"
。
您可以做的是生成从现在到 49 小时内每分钟的所有时间戳(考虑 DST 更改),手动进行匹配(棘手的部分)并报告第一个匹配的时间戳。
或者你可以使用克罗尼特 python
模块:
python -c '
from croniter import croniter
from datetime import datetime
iter = croniter("3 9 * * *", datetime.now())
print(iter.get_next(datetime))'
对于延迟:
$ 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
不过,请注意 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
cron
它本身会通过避免在时间倒退时运行作业两次来解决这个问题,或者在时间向前推进时避免在轮班后运行跳过的作业。
答案2
碰巧的是, shell的内置%T
格式确实支持printf
ksh93
标准 crontab 规范作为输入。
$ ksh93 -c 'printf "%(%F %T)T\n" now "30 9 * * *"'
2017-11-07 17:06:41
2017-11-08 09:30:00
因此,您可以通过以下方式在几秒钟内获得增量:
#! /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."
请注意,它不支持某些(大多数)cron 实现有时支持的扩展,例如*/5
或 月/日名称或 7 作为星期几,或@reboot
,@hourly
等。
答案3
一种方法是使用专用的Perl 的脚本
#!/usr/local/bin/perl -w
use strict;
use lib './lib';
use Schedule::Cron::Events;
use Getopt::Std;
use Time::Local;
use vars qw($opt_f $opt_h $opt_p);
getopts('p:f:h');
if ($opt_h) { usage(); }
my $filename = shift || usage();
my $future = 2;
if (defined $opt_f) { $future = $opt_f; }
my $past = 0;
if (defined $opt_p) { $past = $opt_p; }
open (IN, '<$filename') || die "Unable to open '$filename' for read: $!";
while(<IN>) {
my $obj = new Schedule::Cron::Events($_) || next;
chomp;
print "# Original line: $_\n";
if ($future) {
for (1..$future) {
my $date = localtime( timelocal($obj->nextEvent) );
print "$date - predicted future event\n";
}
}
$obj->resetCounter;
if ($past) {
for (1..$past) {
my $date = localtime( timelocal($obj->previousEvent) );
print "$date - predicted past event\n";
}
}
print "\n";
}
close IN;
sub usage {
print qq{
SYNOPSIS
$0 [ -h ] [ -f number ] [ -p number ] <crontab-filename>
Reads the crontab specified and iterates over every line in it, predicting when
each cron event in the crontab will run. Defaults to predicting the next 2 events.
-h - show this help
-f - how many events predited in the future. Default is 2
-p - how many events predicted for the past. Default is 0.
EXAMPLE
$0 -f 2 -p 2 ~/my.crontab
\$Revision\$
};
exit;
}
=pod
=head1 NAME
cron_event_predict - Reads a crontab file and predicts when event will/would have run
=head1 SYNOPSIS
cron_event_predict.plx [ -h ] [ -f number ] [ -p number ] <crontab-filename>
=head1 DESCRIPTION
A simple utility program mainly written to provide a worked example of how to use the module,
but also of some use in understanding complex or unfamiliar crontab files.
Reads the crontab specified and iterates over every line in it, predicting when
each cron event in the crontab will run. Defaults to predicting the next 2 events.
These are the command line arguments:
-h - show this help
-f - how many events predited in the future. Default is 2
-p - how many events predicted for the past. Default is 0.
Here's an example, showing the default of the next 2 predicted occurences of the each cron job:
dev~/src/cronevent > ./cron_event_predict.plx ~/bin/crontab
# Original line: 1-56/5 * * * * /usr/local/mrtg-2/bin/mrtg /home/admin/mrtg/mrtg.cfg
Thu Sep 26 00:41:00 2002 - predicted future event
Thu Sep 26 00:46:00 2002 - predicted future event
# Original line: 34 */2 * * * /home/analog/analogwrap.bash > /dev/null
Thu Sep 26 02:34:00 2002 - predicted future event
Thu Sep 26 04:34:00 2002 - predicted future event
# Original line: 38 18 * * * /home/admin/bin/allpodscript.bash > /dev/null
Thu Sep 26 18:38:00 2002 - predicted future event
Fri Sep 27 18:38:00 2002 - predicted future event
And here's an example showing past events too:
dev~/src/cronevent > ./cron_event_predict.plx -f 1 -p 3 ~/bin/crontab
# Original line: 1-56/5 * * * * /usr/local/mrtg-2/bin/mrtg /home/admin/mrtg/mrtg.cfg
Thu Sep 26 00:41:00 2002 - predicted future event
Thu Sep 26 00:36:00 2002 - predicted past event
Thu Sep 26 00:31:00 2002 - predicted past event
Thu Sep 26 00:26:00 2002 - predicted past event
# Original line: 34 */2 * * * /home/analog/analogwrap.bash > /dev/null
Thu Sep 26 02:34:00 2002 - predicted future event
Thu Sep 26 00:34:00 2002 - predicted past event
Wed Sep 25 22:34:00 2002 - predicted past event
Wed Sep 25 20:34:00 2002 - predicted past event
# Original line: 38 18 * * * /home/admin/bin/allpodscript.bash > /dev/null
Thu Sep 26 18:38:00 2002 - predicted future event
Wed Sep 25 18:38:00 2002 - predicted past event
Tue Sep 24 18:38:00 2002 - predicted past event
Mon Sep 23 18:38:00 2002 - predicted past event
用法
crontab -l | perl cron_event_predict.plx /dev/stdin
或者
crontab -l > /tmp/crontab
perl cron_event_predict.plx /tmp/crontab
例子
# Original line: 10,16,30,50 * * * * /path/to/script.bash
Sat Jan 7 08:50:00 2023 - predicted future event
Sat Jan 7 09:10:00 2023 - predicted future event