Run a perl or shell script cron job on the first Monday or the Nth weekday of the month

by on July 5, 2007 · 15 comments· LAST UPDATED July 5, 2007

in , ,

This is a classic problem. One of our FAQ is about cron job. I received lots of email with a question:

How do I run my script on 3rd Monday or 4th Friday only?

Cron does not offer this kind of facility i.e. you cannot run a script on the Nth weekday of the month.

However with one shell liner you can force to run a script on a given day:

Consider following date command, it will print day:
$ date +%a
Output:

Thu

You can compare output with weekday name using bash test [exrp ] syntax and the control operators && (AND list), you can write:
$ [ $(date '+%a') == 'Thu' ] && echo 'Today is Thu, run a command' || echo 'Noop'

First echo command get exectued only on Thursday. Now all you have to do is write a cron job to execute on first Monday:
# crontab -e
Now append code as follows:
# Run a script called myscript.sh on First Monday at 11:30:
30 11 1-7 * Mon [ "$(date '+%a')" == "Mon" ] && /path/to/myscript.sh

Hope this small tip will save your day. Please do share some of your favorite bash / shell scripting hacks in the comments. I will highlight some of the best in next shell scripting post.

See also:

TwitterFacebookGoogle+PDF versionFound an error/typo on this page? Help us!

{ 15 comments… read them below or add one }

1 Scott Carlson July 5, 2007 at 10:00 pm

Nice trick, but the crontab is incorrect. As written it will run on all mondays. See crontab(5): “Note: The day of a command’s execution…”

# Run a script called myscript.sh on First Monday at 11:30:
30 11 1-7 * * [ "$(date '+%a')" == "Mon" ] && /path/to/myscript.sh

Reply

2 Ram March 3, 2011 at 7:32 pm

Hi, I wanted to run a script first Thursday of the every month. I added the script in crontab as per your suggesition. It seems somehow it didn’t work.
syntax:

32 13 1-7 * * ["$(date '+%a')" == "Thu"]&&/warehouse/db2scripts/db2_test.ksh > /tmp/db2_test.del

Can you please let me know if i did anything wrong.

Regards,
Ram.

Reply

3 SREEKUMAR September 17, 2007 at 2:04 am

Hi,
I need to execute a script file with the crontab.
I just enter the entry in cronfile and it is not working…
But I can exectute the script manually from the same location with out any issues…

Please advice on this
# Minute Hour Day of Month Month of Year Day of Week Command
57 * * * * sudo /var/opt/R_5.0.0/WebNMS/mysql/bin/mysqlbackup.sh

Reply

4 parashar October 1, 2007 at 7:31 am

what i do to run my script automatically on last day of every month?

Reply

5 Nilay December 6, 2007 at 6:03 am

Just to share few lines regarding the problem I faced while setting up shell script thru cron …
Make sure you set at the very top of your script the directory path where you script lies, or else your script will crash using the relative path …
use …
cd `dirname $0`
This will take cron to your scripts directory and execute it form there ..hope it will save some1s time.

Reply

6 thegetpr March 12, 2008 at 1:03 pm

how to add php script to cron job

Reply

7 Alan March 22, 2008 at 2:00 am

In answer to thegetpr’s question, try this to run a PHP script from cron

50 23 * * * lynx -dump http://www.example.com/scrip.php

Reply

8 radar August 2, 2008 at 5:31 am

Whoever put comment #4 it saved me a lot of time, I had a problem running the script in cron, but it did it!

Thanks a lot for your help.

Reply

9 James September 10, 2008 at 10:27 pm

I should have read the responses. Post 1 is right. I set this up and discovered the same thing.

Thanks for the tip anyway though it certainly helped me.

Reply

10 Eric February 10, 2010 at 6:27 pm

What is the syntax to run it every other Monday?

Reply

11 Sandeep Sonawane February 11, 2010 at 5:19 am

Hi ,
I don’t understanding why my perl script is not executing through crontab .
but it runs properly if we run it at command prompt by typing “perl $path_of_script”.
I found that cron daemon reads the line “perl $path_of_script” as command at proper timing defined in crontab and logs it in /var/log/cron.
But it is not executing.
I think it may be issue of environmental variables for cron daemon.
How to debug this issue ?
Thanks for help in advance.

Reply

12 brian June 7, 2010 at 11:41 pm

Note that you must escape (\) the % in a crontab entry, otherwise cron will treat the % as a newline and feed the rest of the command line as STDIN. The correct command would be:
30 11 1-7 * * [ "$(date '+\%a')" == "Mon" ] && /path/to/myscript.sh

Thanks for the great tip

Reply

13 mrevans July 30, 2013 at 4:47 pm

I had to use the escape as Brian noted. I also had to use a single ‘=’ for the test. I could use ‘==’ but the job would error out if I had any spaces around the ‘==’.

These worked for me on Debian 6.0.7:

0 9 29-31 * * [ "$(date '+\%a')"=="Wed" ] && echo “today is the fifth Wednesday” > ~/isWed || echo “today is not the fifth Wednesday” > ~/isWed

0 9 29-31 * * [ "$(date '+\%a')" = "Tue" ] && echo “today is the fifth tuesday” > ~/isTues || echo “today is not the fifth Tuesday” > ~/isTues

ymmv

Reply

14 Liam Lord May 1, 2014 at 3:41 pm

Just found this by accidentally clicking a wrong link, and I have to say this article is wrong.

Cron has a perfectly good way to check the weekday, it’s the last date based param:

Min Hour Date Month DoW Username Command

To run something on the first Monday of every month use:

0 0 1-7 * 1 root command

To run on the second thursday you can use:

0 0 8-15 * 4 root command

To run every sunday:

0 0 * * 0 root command

To run every second wednesday:

0 0 */2 * 3 root command

Reply

15 brian May 1, 2014 at 6:17 pm

@Liam: It’s you who are incorrect. When specifying both DoM and DoW, the command will be run if EITHER of them matches, so:
0 0 1-7 * 1 root command
will run every day on days 1-7, and ALSO on day 1 of the month.

Please see the crontab(5) man page (man 5 crontab).

Reply

Leave a Comment

Tagged as: , , , , , , , , ,

Previous post:

Next post: