, 2 min read

Scheduling Cron Jobs on Business Days

I found a marvelous way to run jobs on certain business days via cron. The solution was depicted in Scheduling Cron Jobs on Business Days and it was written by a user named rdcwayx. The idea is to use the output of cal and some Awk or Perl string-trickery.

The output of cal looks like this

    February 2014      
    Su Mo Tu We Th Fr Sa  
                       1  
     2  3  4  5  6  7  8  
     9 10 11 12 13 14 15  
    16 17 18 19 20 21 22  
    23 24 25 26 27 28

Here is the procedure, named chkbusday, to decide whether current date is $1-st business day of the month. The point is to extract the numbers below Mo-Fr, then split them, put each number into an array. The array index is $1-st business day, disregarding holidays.

#!/usr/bin/perl -W

use strict;
my ($i,$s) = (0,"");
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
exit 1 if ($#ARGV < 0);
open(IN,"cal -h |") || exit 2;    # turn off highligthing of today
while (<IN>) {
        next if (++$i <= 2);
        $s .= substr($_,2,15);
}
my @F = split(/\s+/,$s);
exit 3 if ($#F < $ARGV[0]);
exit ($F[ $ARGV[0] ] != $mday);

So with chkbusday it is now easy, for example, to check whether the current day is the fourth business day. Just prepend each command in cron with

chkbusday 4 && command

A sample cron configuration is given below using above test for specific business day within a month.

# On 4th business day at 12:03 remind people
3 12 1-24 * *   chkbusday 4 && some-command
#
# On 5th business day at 09:03 remind again
3 9 1-24 * *    chkbusday 5 && another-command

It looks that using cal and cutting out parts of its output is easier than redoing the calculation in ncal. Source code of ncal is here: ncal.c.

Watch out for the difference between cal and ncal. Ubuntu uses ncal by default. On Red Hat one can use "cal -s" for starting with Sunday -- this option is not available in Ubuntu. On Ubuntu "cal -h" suppresses highlighting. This option is not available on Red Hat's version of cal.