Cron task to work on the last day of the month

I need to create a cron job that will work on every last day of the month. I will create it from cpanel.

Any help is appreciated. Thanks

+60
posix cron automation
May 26 '11 at 13:22
source share
12 answers

Perhaps the easiest way is to simply complete three separate tasks:

55 23 30 4,6,9,11 * myjob.sh 55 23 31 1,3,5,7,8,10,12 * myjob.sh 55 23 28 2 * myjob.sh 

This will work on February 28th, although even in leap years, if this is a problem, you need to find another way.




However, as a rule, it’s both much easier and the right way to start work as soon as possible on the first day of each month, with something like:

 0 0 1 * * myjob.sh 

and change the script to process the data of the previous month.

This eliminates any difficulties that you may encounter when it turns out which day is the last month, and also ensures the availability of all data for that month if you are working with data. Five minutes before midnight on the last day of the month, you can see that you are missing something that happens between noon and noon.

This is the usual way to do this anyway for most tasks at the end of the month.




If you still want to run it on the last day of the month, one of them is simply to determine whether tomorrow will be the first (either as part of your script or crontab itself).

So something like:

 55 23 28-31 * * [[ "$(date --date=tomorrow +\%d)" == "01" ]] && myjob.sh 

should be a good start if you have a relatively smart date program.

If your date program is not advanced enough to give you relative dates, you can simply put together a very simple program to give you the day of the month tomorrow (you don't need the full date power), for example:

 #include <stdio.h> #include <time.h> int main (void) { // Get today, somewhere around midday (no DST issues). time_t noonish = time (0); struct tm *localtm = localtime (&noonish); localtm->tm_hour = 12; // Add one day (86,400 seconds). noonish = mktime (localtm) + 86400; localtm = localtime (&noonish); // Output just day of month. printf ("%d\n", localtm->tm_mday); return 0; } 

and then use (assuming you named it tomdom for "tomorrow of the month"):

 55 23 28-31 * * [[ "$(tomdom)" == "1" ]] && myjob.sh 

Although you might want to add error checking, since time() and mktime() can return -1 if something goes wrong. The above code, for reasons of simplicity, does not take this into account.

+113
May 26 '11 at
source share
β€” -

There is a slightly shorter method that can be used similarly to one of the above. I.e:

 [ $(date -d +1day +%d) -eq 1 ] && echo "last day of month" 

In addition, the crontab record can be updated to check only on 28-31, because it makes no sense to run it on other days of the month. What will give you:

 0 23 28-31 * * [ $(date -d +1day +%d) -eq 1 ] && myscript.sh 
+38
Aug 26 '11 at 11:41
source share

Configure the cron job to run on the first day of the month. Then change the system clock one day in advance.

+22
May 26 '11 at 13:43
source share

How about this, after Wikipedia?

 55 23 L * * /full/path/to/command 
+10
Mar 15 '12 at 11:17
source share

Adapting the paxdiablo solution, I launch February 28 and 29. Data from the 29th is overwriting the 28th.

 # min hr date month dow 55 23 31 1,3,5,7,8,10,12 * /path/monthly_copy_data.sh 55 23 30 4,6,9,11 * /path/monthly_copy_data.sh 55 23 28,29 2 * /path/monthly_copy_data.sh 
+8
May 17 '13 at 7:40
source share

You can configure the cron job to run on every day of the month and run the shell script as shown below. This script determines if tomorrow's number will be less than today (i.e. if tomorrow is a new month), and then will do whatever you need.

 TODAY=`date +%d` TOMORROW=`date +%d -d "1 day"` # See if tomorrow day is less than today's if [ $TOMORROW -lt $TODAY ]; then echo "This is the last day of the month" # Do stuff... fi 
+5
May 26 '11 at 13:25
source share
 00 23 * * * [[ $(date +'%d') -eq $(cal | awk '!/^$/{ print $NF }' | tail -1) ]] && job 

Check out the related question on the unix.com forum.

+4
May 26 '11 at 13:26
source share

Some cron implementations support the L flag to represent the last day of the month.

If you are lucky to use one of these implementations, this is simple:

 0 55 23 L * ? 

This will work at 11:55 pm on the last day of each month.

http://www.quartz-scheduler.org/documentation/quartz-1.x/tutorials/crontrigger

+4
Sep 05 '13 at 1:27
source share

You can simply plug in all the responses in one cron line and use only the date command.

Just check the difference between the day of the month today and tomorrow:

 0 23 * * * root [ $(expr $(date +\%d -d '1 days') - $(date +\%d) ) -le 0 ] && echo true 

If these differences are below 0, this means that we are changing the month and the last day of the month.

+3
May 29 '11 at 16:49
source share

For a safer method in crontab based on @Indie's solution (using the absolute path to date + $() does not work on all crontab systems):

 0 23 28-31 * * [ `/bin/date -d +1day +\%d` -eq 1 ] && myscript.sh 
+3
Mar 06 2018-12-12T00:
source share
 ######################################################### # Memory Aid # environment HOME=$HOME SHELL=$SHELL LOGNAME=$LOGNAME PATH=$PATH ######################################################### # # string meaning # ------ ------- # @reboot Run once, at startup. # @yearly Run once a year, "0 0 1 1 *". # @annually (same as @yearly) # @monthly Run once a month, "0 0 1 * *". # @weekly Run once a week, "0 0 * * 0". # @daily Run once a day, "0 0 * * *". # @midnight (same as @daily) # @hourly Run once an hour, "0 * * * *". #mm hh Mday Mon Dow CMD # minute, hour, month-day month DayofW CMD #........................................Minute of the hour #| .................................Hour in the day (0..23) #| | .........................Day of month, 1..31 (mon,tue,wed) #| | | .................Month (1.12) Jan, Feb.. Dec #| | | | ........day of the week 0-6 7==0 #| | | | | |command to be executed #VVVVVV * * 28-31 * * [ `date -d +'1 day' +\%d` -eq 1 ] && echo "Tomorrow is the first today now is `date`" >> ~/message 1 0 1 * * rm -f ~/message * * 28-31 * * [ `date -d +'1 day' +\%d` -eq 1 ] && echo "HOME=$HOME LOGNAME=$LOGNAME SHELL = $SHELL PATH=$PATH" 
+3
Feb 28 '15 at 17:53
source share

How about this?

change user .bashprofile add:

 export LAST_DAY_OF_MONTH=$(cal | awk '!/^$/{ print $NF }' | tail -1) 

Then add this entry to crontab:

 mm hh * * 1-7 [[ $(date +'%d') -eq $LAST_DAY_OF_MONTH ]] && /absolutepath/myscript.sh 
+1
Apr 25 '14 at 11:23
source share



All Articles