Hello nuns and monks!
dont know if is so cool.. anyway I was playing with cron entries while I discovered Algorithm::Cron and it's cool method
next_time that suddenly provoked a oneliner moment:
perl -MAlgorithm::Cron -E "say scalar localtime (Algorithm::Cron->new(base => 'local',crontab => $ARGV[0])->next_time(time)) " "0 9 12 4 *" which prints Fri Apr 12 09:00:00 2019
But this was not cool enough. The following program by other hand parse a cron file or the output of cron -l or some input pasted and shows an ordered list of next commands cron will run.
It accepts input from a pipe, from a file with -f filename and if nothing was given it expects some input to be pasted followed by CTRL-Z or CTRL-D (windows or linux).
Instead of the above input you can use -c "crontab-entry" to parse a solitary crontab entry.
And dulcis in fundo, with the -n N parameter the program will show next N occurrences of the scheduled programs
use strict;
use warnings;
use Getopt::Long;
use Algorithm::Cron;
my $file;
my $howmany;
my $crontab;
my $help;
my @lines;
my $helptext = "USAGE:\n $0 [ [-f filename | -c STRING] -n N]\n\n".
" $0 -f filename\n".
" $0 -f filename -n 2\n".
" crontab -l | $0 \n".
" crontab -l | $0 -n 2\n".
" cat filename | $0\n".
" cat filename | $0 -n 3\n".
" $0 -c 'crontab entry'\n".
" $0 -c 'crontab entry' -n 5\n".
" $0 (paste some content followed by CTRL-D or CTRL-Z on
+a newline)\n".
" $0 -n 4 (paste some content followed by CTRL-D or CTRL-
+Z on a newline)\n".
" $0 -h (print this help)\n";
GetOptions ("f|file=s" => \$file,
"n=i" => \$howmany,
"c|crontab=s" => \$crontab,
"h|help" => \$help)
or die( $helptext );
print $helptext and exit if $help;
if ( $crontab ) { @lines = $crontab }
elsif ( $file and -e -f -r $file){
open my $fh, '<', $file or die;
@lines = <$fh>;
}
else{ @lines = <> }
foreach my $line (
sort {
Algorithm::Cron->new( base => 'local',
crontab => join' ',(split /\s+|\t/,$a)[0..4])->next_ti
+me(time)
<=>
Algorithm::Cron->new( base => 'local',
crontab => join' ',(split /\s+|\t/,$b)[0..4])->next_ti
+me(time)
}
grep { /^(\d|\*)/ } @lines
){
my @parts = split /\s+|\t/,$line;
my $now = time;
my $repeat = $howmany;
print scalar localtime ( Algorithm::Cron->new( base => 'local',
crontab => join' ', @parts[0..4])->next_ti
+me($now)
);
print " => ( @parts[0..4] )",($crontab ? "" : " => @parts[5..$#par
+ts]"),"\n";
if ( --$repeat ){
while( $repeat > 0){
$now = Algorithm::Cron->new( base => 'local',
crontab => join' ', @parts[0..4])->next_time(
+$now );
print scalar localtime ( Algorithm::Cron->new( base => 'lo
+cal',
crontab => join' ', @parts[0..4])->next_ti
+me($now)
);
print "\n";
$repeat--;
}
}
}
given a sample file the following example show the usage:
cat crontab.txt
# Crontab Environmental settings
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
00 3 * 7 0 /path/to/command
#15 20 * 1-7 * /path/to/command2
*/30 7,21 1-15 1 * /path/to/another/command
# m h dom mon dow user command
21 * * * * root cd / && run-parts --report /etc/cron.hourly
0,30 6 * * * root test -x /usr/sbin/blah
#47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-pa
+rts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/blahblah || ( cd / && run-pa
+rts )
cat crontab.txt | perl cron-explain.pl
Tue Nov 27 14:21:00 2018 => ( 21 * * * * ) => root cd / && run-parts -
+-report /etc/cron.hourly
Wed Nov 28 06:00:00 2018 => ( 0,30 6 * * * ) => root test -x /usr/sbin
+/blah
Sat Dec 1 06:52:00 2018 => ( 52 6 1 * * ) => root test -x /usr/sbin/b
+lahblah || ( cd / && run-parts )
Tue Jan 1 07:00:00 2019 => ( */30 7,21 1-15 1 * ) => /path/to/another
+/command
Sun Jul 7 03:00:00 2019 => ( 00 3 * 7 0 ) => /path/to/command
cat crontab.txt | perl cron-explain.pl -n 3
Tue Nov 27 14:21:00 2018 => ( 21 * * * * ) => root cd / && run-parts -
+-report /etc/cron.hourly
Tue Nov 27 15:21:00 2018
Tue Nov 27 16:21:00 2018
Wed Nov 28 06:00:00 2018 => ( 0,30 6 * * * ) => root test -x /usr/sbin
+/blah
Wed Nov 28 06:30:00 2018
Thu Nov 29 06:00:00 2018
Sat Dec 1 06:52:00 2018 => ( 52 6 1 * * ) => root test -x /usr/sbin/b
+lahblah || ( cd / && run-parts )
Tue Jan 1 06:52:00 2019
Fri Feb 1 06:52:00 2019
Tue Jan 1 07:00:00 2019 => ( */30 7,21 1-15 1 * ) => /path/to/another
+/command
Tue Jan 1 07:30:00 2019
Tue Jan 1 21:00:00 2019
Sun Jul 7 03:00:00 2019 => ( 00 3 * 7 0 ) => /path/to/command
Sun Jul 14 03:00:00 2019
Sun Jul 21 03:00:00 2019
perl cron-explain.pl -c "2-5 9 12 4 *" -n 4
Fri Apr 12 09:02:00 2019 => ( 2-5 9 12 4 * )
Fri Apr 12 09:03:00 2019
Fri Apr 12 09:04:00 2019
Fri Apr 12 09:05:00 2019
have fun!
L*
There are no rules, there are no thumbs..
Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.