Cron jobs can be scheduled based on minute, hour, day of month, month or by the day of the week. Flexible as it may seem, there is actually no simple way to schedule a job to be run on the last day of every month.
To overcome the problem, we will need to perform the logic using shell scripts.
The solution is to get the day of month for today and compare it to the last day of the month from the output of the cal
command. If they match, then it’s the last day of the month.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#!/bin/sh # function to check if it's the last day of the month is_last_day_of_month () { dom=`date +%d` cdom=`echo `cal` | awk '{ print $NF }'` [ $dom -eq $cdom ] && echo 1 echo 0 } ldom=`is_last_day_of_month` # exit if it's not the last day of the month [ "$ldom" -ne 1 ] && exit 1 # run jobs that need to be run on the last day of the month exec "$@" |
Save the script as ldom.sh
(ldom = Last Day of Month) and make it executable. If the script determines that it is being run on the last day of the month, it will try to execute the arguments that are passed to it. If it’s not the last day, the script will not do anything.
So, let’s say that you need to run the “last_day_of_month_batch.sh
” script on the last day of every month at 8pm. You will need to modify the crontab as follows.
1 |
00 20 * * * /path/to/ldom.sh /path/to/last_day_of_month_batch.sh |
The ldom.sh
script will only run the last_day_of_month_batch.sh
script if it’s the last day of the month, else it will not be executed.
Do not schedule the script to be run just around midnight as there’s a small (almost impossible) possibility that the is_last_day_of_month
function might return unexpected results.
Another way of checking for the last day of the month is to use the logic found in Shell Script to Calculate Tomorrow’s Date. The idea is to get today’s date and tomorrow’s date and check if the value of the month changes. If there’s a change, then it’s the last day of the month. But this logic is a bit too long to implement!