Cron expression to execute on the “second last working day” of the month

cronregular expressions

I need your help to contruct a cron job to run the second last working day of every month. I can do LW as shown below but i am not sure how to do second last. I need your help and advise here please.

@MWE has kindly provided me a possible solution but it does not seem to work in all test scenarios.

code:
#!/bin/bash
date
WEEKDAY=$(date +%u)
# If detect the montday in 2 days.
if [ $(date +%d -d "2 day") -eq 1 ] && [ ${WEEKDAY} -lt 5 ] ; then
   echo "This is the 2. last working day of the month"
# If detect the montday in 5 days.
elif [ $(date +%d -d "5 day") -eq 1 ] && [ ${WEEKDAY} -eq 5 ] ; then
   echo "This is the 2. last working day of the month"
else
  exit
fi

Test scenario:
Ive amended the system date on the server to be 29th August 2019 (**this is the second last working date on the system)

the script in debug mode exits out:

[oracle@rdbauroral01v ~]$ bash -x ./crontest.sh
+ date
Thu Aug 29 13:28:20 UTC 2019
++ date +%u
+ WEEKDAY=4
++ date +%d -d '2 day'
+ '[' 31 -eq 1 ']'
++ date +%d -d '5 day'
+ '[' 03 -eq 1 ']'
+ exit

appreciate your help here..

Best Answer

Just as simple idea to solve it in the script not in crontab.:

Last day of a month is always this day, when tomorrow = 1. of a month.

That means: Let get out the current date from epoch in seconds, and add 24h hours. Then lets get out what day of month it is:

TIMESTAMP=$(date +%s)
TIMESTAMP_TOMORROW=$(( $TIMESTAMP + 86400 ))

Figure out the month day of tomorrow:

DAYOFMONTH=$(date --date="@${TIMESTAMP_TOMORROW}" +%e)

if DAYOFMONTH == 1 today is the last day of month. Do, what you want, then. if not == 1, exit.

Alternatives can be found here: https://stackoverflow.com/questions/6139189/cron-job-to-run-on-the-last-day-of-the-month

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

or:

0 23 28-31 * * [ `/bin/date -d +1day +\%d` -eq 1 ] && myscript.sh

Last but not Least. Multiply $(( $TIMESTAMP + 86400 * 2 )) , for the 2. last day.

or:

TOMORROW=$(date +%d -d "2 day")

or:

[ $(/bin/date -d +2day +\%d) -eq 1 ]