views:

48

answers:

3

Is it possible to find all entries in a crontab that run between time X and time Y without having to parse the cron time entries myself? I'm mainly concerned with time hour and minute, not so much the other 3 time fields.

A: 

You could copy and paste the crontab file into Excel and then create a few functions that do this. Since the time fields are always in the same place, your columns in Excel would correspond to the timeframe in which that command is executed.

You'll have to write your formula so that is accounts for single integer values and repeating values (like 10 versus */10).

If your crobtab file changes a lot and you have many entries, then you could probably write a php script to parse this information pretty quickly.

Scott Harwell
this requires parsing the crontab myself, which I would do in perl if there are no bash builtins to handle this
frankc
@user: There definitely aren't any Bash builtins to handle this. Bash has no idea at all about `cron`. I don't know of any utilities to do this either. A simple script is all it would take.
Dennis Williamson
@Scott: Why would you use Excel? That would require copying the file to a computer running Windows. It would be like using a backhoe to hammer in a finish nail. The correct way to do this would be with a script (Perl, AWK, etc.).
Dennis Williamson
@dennis I didnt expect bash to know anything about cron per se, rather that there might be some common utility for it. I have a pretty good knowledge of what's available, but I'd prefer to check before I roll my own. It's surprising to me that such a thing does not exist given cron's importance and long history.
frankc
+1  A: 

Anything is possible but you will have to parse crontab yourself.

There are no simple answers, but just because I can here's a partial solution in 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

Call like

cron_between 09:00 16:59

This certainly won't work for complex time specifications (e.g. */2) and only reports on the first part of the command. All of this can be corrected, but probably you'd be better off doing it in perl or something.

Sorpigal
thanks for the effort. I am already doing this in perl now. It's surprisingly annoying to do if you want to support the full cron spec of *,-, and /
frankc
A: 
frankc