找到在给定时间之间运行的cron作业

时间:2010-10-29 15:41:11

标签: linux bash unix cron

是否可以在crontab中找到在时间X和时间Y之间运行的所有条目,而不必自己解析cron时间条目?我主要关注时间和时间,而不是其他3个时间段。

4 个答案:

答案 0 :(得分:3)

一切皆有可能,但你必须自己解析crontab。

没有简单的答案,只是因为我可以在bash中找到部分解决方案。

    #!/bin/bash

    start="${1-0:0}"
    end="${2-0:0}"
    start_hour=$(cut -d: -f1 <<<"$start")
    end_hour=$(cut -d: -f1 <<<"$end")
    start_min=$(cut -d: -f2 <<<"$start")
    end_min=$(cut -d: -f2 <<<"$end")

    # leading zeroes would be bad
    let start_hour=10#${start_hour}
    let end_hour=10#${end_hour}
    let start_min=10#${start_min}
    let end_min=10#${end_min}

    cat /etc/crontab | \
            grep -v ^\# | \
            grep -E -v '^([a-zA-Z]+)' | \
            awk '{print $1, $2, $7}' | \
    while read line ; do
            if [ ! -z "$line" ] ; then
                    h=$(cut -d' ' -f2 <<<"$line")
                    m=$(cut -d' ' -f1 <<<"$line")
                    cmd=$(cut -d' ' -f3- <<<"$line")

                    if [ "$h" = '*' ] || ( [ $h -ge $start_hour ] && [ $h -le $end_hour ] ) ; then
                            if [ "$m" = '*' ] || ( [ $m -ge $start_min ] && [ $m -le $end_min ] ) ; then
                                    echo $cmd
                            fi
                    fi
            fi
    done

一样打电话
cron_between 09:00 16:59

这肯定不适用于复杂的时间规范(例如* / 2),只报告命令的第一部分。所有这一切都可以得到纠正,但是你可能会更好地在perl或其它东西上做这件事。

答案 1 :(得分:2)

由于在没有解析cron的情况下这似乎不可能,我决定自己在perl中写它:
(不确定为什么格式化为fubar)


#!/usr/bin/perl -w
use strict;
use Set::CrossProduct;

my $begin; my $end;

if($ARGV[0] && $ARGV[0] =~ /before/i){ $begin = 0; $end = $ARGV[1];
} elsif($ARGV[0] && $ARGV[0] =~ /after/i){ $end = 2400; $begin = $ARGV[1]; } else{ $begin = $ARGV[0]; $end = $ARGV[1]; }

if(!defined($begin) || !defined($end)){ print STDERR "Invalid Arguments\n"; exit 1; }

my @crontab = `crontab -l`;

foreach my $cronjob (@crontab){ chomp $cronjob;

next if $cronjob =~ /^ *\#/ ||$cronjob =~ /^ *$/  ;

#print "in: $cronjob\n";

my ($min,$hour,$day_of_month,$month,$day_of_week, @cmd) = split(/ /, $cronjob);

my @mins = expandRange($min,0,59);
my @hours = expandRange($hour,0,23);

my $cp = Set::CrossProduct->new([\@hours,\@mins]);

my $combos = $cp->combinations();

foreach my $time ( map { $_->[0]*100 + $_->[1] } @$combos){
if($time >= $begin && $time <= $end){
    print $cronjob,"\n";
    last; #don't print the job n times, just once
}
}

}

sub expandRange{

my ($in,$begin,$end) = @_;
#print "in: ($in)[$begin:$end]\n";
my @range;

my @vals = split(/,/,$in);
foreach my $val (@vals){
my $mult = 1;
if($val =~ /\/(.+)$/){
    $mult = $1;
    $val =~ s/\/(.+)//;
}

if($in =~ /\*/){
    @range = grep { $_ % $mult == 0 && $_ >= $begin &&  $_ <= $end  } $begin..$end;
}
elsif($val =~ /[\-:]/){
    my ($first, $last) = split(/[\-:]/,$val);
    push(@range, grep {  $_ % $mult == 0 && $_ >= $begin &&  $_ <= $end } $first..$last);
}
elsif($val >= $begin &&  $val <= $end) {
    push(@range, $val);
}
}

my %unique;
@unique{@range} = 1;

return sort keys %unique;

}

答案 2 :(得分:1)

您可以将crontab文件复制并粘贴到Excel中,然后创建一些执行此操作的函数。由于时间字段始终位于同一位置,因此Excel中的列将对应于执行该命令的时间范围。

您必须编写公式,以便考虑单个整数值和重复值(例如10对* / 10)。

如果您的crobtab文件发生了很大变化并且您有很多条目,那么您可能会编写一个php脚本来快速解析这些信息。

答案 3 :(得分:1)

您可以使用Ruby 1.8.7 gem "crontab-parser"来解析crontab,然后在两个时间戳之间迭代每一分钟,在每个crontab条目上调用should_run?

require 'rubygems'
require 'crontab-parser'

start_time = Time.parse(ARGV[0])
end_time   = Time.parse(ARGV[1])

# CrontabParser barfs on env variable setting in a crontab, so just skip them
cron_data = File.readlines(ARGV[2]).select {|line| line =~ /^[0-9*]/}
cron  = CrontabParser.new(cron_data.join("\n"))
(start_time..end_time).each do |timestamp|
  next unless timestamp.sec.to_i == 0
  cron.each do |cron_entry|
    if cron_entry.should_run?(timestamp)
      puts "#{timestamp}\t#{cron_entry.cmd}"
    end
  end
end

所以,如果你的crontab.txt看起来像这样:

*   *   *   *   *   foo
18  15  *   *   *   bar

然后使用date或类似的输出以及包含crontab的文件调用脚本:

ruby cron_report.rb "Sat Mar 3 02:07:32 UTC 2012" "Sat Mar 3 02:21:32 UTC 2012" crontab.txt

你会得到这样的输出:

Sat Mar 03 15:17:00 UTC 2012    *   *   *   *   *   foo
Sat Mar 03 15:18:00 UTC 2012    *   *   *   *   *   foo
Sat Mar 03 15:18:00 UTC 2012    18  15  *   *   *   bar
Sat Mar 03 15:19:00 UTC 2012    *   *   *   *   *   foo
Sat Mar 03 15:20:00 UTC 2012    *   *   *   *   *   foo