'CRON job to run on the last day of the month
I need to create a CRON job that will run on the last day of every month. I will create it using cPanel.
Any help is appreciated. Thanks
Solution 1:[1]
There's a slightly shorter method that can be used similar to one of the ones above. That is:
[ $(date -d +1day +%d) -eq 1 ] && echo "last day of month"
Also, the crontab entry could be update to only check on the 28th to 31st as it's pointless running it the other days of the month. Which would give you:
0 23 28-31 * * [ $(date -d +1day +%d) -eq 1 ] && myscript.sh
Solution 2:[2]
What about this one, after Wikipedia?
55 23 L * * /full/path/to/command
Solution 3:[3]
Adapting paxdiablo's solution, I run on the 28th and 29th of February. The data from the 29th overwrites 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
Solution 4:[4]
For AWS Cloudwatch cron implementation (Scheduling Lambdas, etc..) this works:
55 23 L * ? *
Running at 11:55pm on the last day of each month.
Solution 5:[5]
Set up a cron job to run on the first day of the month. Then change the system's clock to be one day ahead.
Solution 6:[6]
You could set up a cron job to run on every day of the month, and have it run a shell script like the following. This script works out whether tomorrow's day number is less than today's (i.e. if tomorrow is a new month), and then does whatever you want.
TODAY=`date +%d`
TOMORROW=`date +%d -d "1 day"`
# See if tomorrow's day is less than today's
if [ $TOMORROW -lt $TODAY ]; then
echo "This is the last day of the month"
# Do stuff...
fi
Solution 7:[7]
For a safer method in a crontab based on @Indie solution (use absolute path to date + $() does not works on all crontab systems):
0 23 28-31 * * [ `/bin/date -d +1day +\%d` -eq 1 ] && myscript.sh
Solution 8:[8]
Some cron implementations support the "L" flag to represent the last day of the month.
If you're lucky to be using one of those implementations, it's as simple as:
0 55 23 L * ?
That will run at 11:55 pm on the last day of every month.
http://www.quartz-scheduler.org/documentation/quartz-1.x/tutorials/crontrigger
Solution 9:[9]
#########################################################
# 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
#V V V V V V
* * 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"
Solution 10:[10]
00 23 * * * [[ $(date +'%d') -eq $(cal | awk '!/^$/{ print $NF }' | tail -1) ]] && job
Check out a related question on the unix.com forum.
Solution 11:[11]
You can just connect all answers in one cron line and use only date command.
Just check the difference between day of the month which is today and will be tomorrow:
0 23 * * * root [ $(expr $(date +\%d -d '1 days') - $(date +\%d) ) -le 0 ] && echo true
If these difference is below 0 it means that we change the month and there is last day of the month.
Solution 12:[12]
55 23 28-31 * * echo "[ $(date -d +1day +%d) -eq 1 ] && my.sh" | /bin/bash
Solution 13:[13]
What about this?
edit user's .bashprofile adding:
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
Solution 14:[14]
The last day of month can be 28-31 depending on what month it is (Feb, March etc). However in either of these cases, the next day is always 1st of next month. So we can use that to make sure we run some job always on the last day of a month using the code below:
0 8 28-31 * * [ "$(date +%d -d tomorrow)" = "01" ] && /your/script.sh
Solution 15:[15]
If the day-of-the-month field could accept day zero that would very simply solve this problem. Eg. astronomers use day zero to express the last day of the previous month. So
00 08 00 * * /usr/local/sbin/backup
would do the job in simple and easy way.
Solution 16:[16]
I found out solution (On the last day of the month) like below from this site.
0 0 0 L * ? *
CRON details:
Seconds Minutes Hours Day Of Month Month Day Of Week Year
0 0 0 L * ? *
To cross verify above expression, click here which gives output like below.
2021-12-31 Fri 00:00:00
2022-01-31 Mon 00:00:00
2022-02-28 Mon 00:00:00
2022-03-31 Thu 00:00:00
2022-04-30 Sat 00:00:00
Solution 17:[17]
Not sure of other languages but in javascript it is possible.
If you need your job to be completed before first day of month node-cron will allow you to set timezone - you have to set UTC+12:00 and if job is not too long most of the world will have results before start of their month.
Solution 18:[18]
Better way to schedule cron on every next month of 1st day
This will run the command foo at 12:00AM.
0 0 1 * * /usr/bin/foo
Solution 19:[19]
Be cautious with "yesterday", "today", "1day" in the 'date' program if running between midnight and 1am, because often those really mean "24 hours" which will be two days when daylight saving time change causes a 23 hour day. I use "date -d '1am -12 hour' "
Solution 20:[20]
In tools like Jenkins, where usually there is no support for L nor tools similar to date, a cool trick might be setting up the timezone correctly. E.g. Pacific/Kiritimati is GMT+14:00, so if you're in Europe or in the US, this might do the trick.
TZ=Pacific/Kiritimati \n H 0 1 * *
Result: Would last have run at Saturday, April 30, 2022 10:54:53 AM GMT; would next run at Tuesday, May 31, 2022 10:54:53 AM GMT.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
