Jed's Journal

Yes. I'm blogging straight from a terminal.

Run bash script on specific time without using cron

April 05, 2018 — Jed Mallen

Everybody knows cron is the go to guy for scheduled jobs in unix. But there are some schedules that don't lend itself to cron beautifully.

As an example, at work I have a healthcheck script running to check if our webapp is running and if not start it. Simple.

The issue comes every Tuesday at 3:30 AM to 5:30 AM we have a maintenance window scheduled. During that time all services will be stopped. So if healthcheck is running it will interfere with that and start it back up. We can simply edit the cronjob right? Sure. Try doing that to several servers. It gets pretty tiring to crontab -e, put a comment on that line for healthcheck, save it. Then exit, ssh to the next server, and the next, and the next. You get the idea.

Also, because the schedule is not 3 to 5, it's 3:30 to 5:30, I need to break the cronjob in 4 lines:

Note: the schedule below is in UTC, the one I described above is EST/EDT

* * * * sun,mon,wed,thu,fri,sat healthcheck.sh
* 0-6,10-23 * * tue healthcheck.sh
0-29 7 * * tue healthcheck.sh
31-59 9 * * tue healthcheck.sh

Fugly right?

And another thing, because the primary schedule we are referenced to is Eastern Standard Time, I need to change the cronjob schedule when DST flips.

So we come to the meat of this post. Below is a way we can reference another timezone and set the schedule when it will run or not. So essentially the cronjob is reduced to this:

* * * * * healthcheck.sh

And the healthcheck script will have this as it's main function:

mwday=2 # 2 is Tuesday in %u
mwstart=0330
mwend=0530
log="/tmp/checktime.log"
currentday=`TZ=America/New_York date +%u`
currentdatetime=`TZ=America/New_York date`
if [ "$currentday" -eq "$mwday" ];then
        currenttime=`TZ=America/New_York date +%H%M`
        if [ "$currenttime" -ge "$mwstart" ] && [ "$currenttime" -le "$mwend" ];then
                date >> $log
                echo "MW detected. We are between $mwstart and $mwend. No healthchecks." >> $log
                echo "$currentdatetime"  >> $log
                exit # exit healthcheck as we are on Maintenance Window
        else
                date >> $log
                echo "It's Tuesday BUT we are NOT between $mwstart and $mwend so run healtcheck.">> $log
                echo "$currentdatetime" >> $log
                main
                logcleanup
        fi
else
        # it's not Tuesday. run healthcheck.
        date >> $log
        echo "It's not Tuesday. Running healthcheck." >> $log
        TZ=America/New_York date >> $log
        main
        logcleanup
fi

Tags: bash, cron, datetime