Найти задания cron, которые выполняются между заданными временами - PullRequest
1 голос
/ 29 октября 2010

Можно ли найти все записи в crontab, которые выполняются между временем X и временем Y, не разбирая записи времени cron самостоятельно?В основном меня интересуют время, часы и минуты, а не три других временных поля.

Ответы [ 4 ]

3 голосов
/ 29 октября 2010

Все возможно, но вам придется разбирать 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 или что-то в этом роде.

2 голосов
/ 29 октября 2010

Поскольку это кажется невозможным без разбора cron, я решил написать сам в perl:
(не уверен, почему форматирование fubar)


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

<p>my $begin;
my $end;</p>

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

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

<p>my @crontab = `crontab -l`;</p>

<p>foreach my $cronjob (@crontab){
    chomp $cronjob;</p>

<pre><code>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;

}

1 голос
/ 03 марта 2012

Вы можете использовать гем Ruby 1.8.7 "crontab-parser" для анализа crontab, а затем перебирать каждую минуту между двумя временными метками, вызывая should_run? для каждой записи в crontab:

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
1 голос
/ 29 октября 2010

Вы можете скопировать и вставить файл crontab в Excel, а затем создать несколько функций, которые делают это.Поскольку поля времени всегда находятся в одном и том же месте, ваши столбцы в Excel будут соответствовать временным рамкам, в которых выполняется эта команда.

Вам нужно будет написать свою формулу, чтобы она учитывала одно целые значения иповторяющиеся значения (например, 10 против * / 10).

Если ваш файл crobtab сильно меняется и у вас много записей, то вы, вероятно, могли бы написать php-скрипт для довольно быстрого анализа этой информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...