≡ Menu

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

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:

Share this on:

Your support makes a big difference:
I have a small favor to ask. More people are reading the nixCraft. Many of you block advertising which is your right, and advertising revenues are not sufficient to cover my operating costs. So you can see why I need to ask for your help. The nixCraft, takes a lot of my time and hard work to produce. If you use nixCraft, who likes it, helps me with donations:
Become a Supporter →    Make a contribution via Paypal/Bitcoin →   

Don't Miss Any Linux and Unix Tips

Get nixCraft in your inbox. It's free:



{ 17 comments… add one }
  • Scott Carlson July 5, 2007, 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

    • Ram March 3, 2011, 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.

  • SREEKUMAR September 17, 2007, 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

  • parashar October 1, 2007, 7:31 am

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

  • Nilay December 6, 2007, 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.

  • thegetpr March 12, 2008, 1:03 pm

    how to add php script to cron job

  • Alan March 22, 2008, 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

  • radar August 2, 2008, 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.

  • James September 10, 2008, 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.

  • Eric February 10, 2010, 6:27 pm

    What is the syntax to run it every other Monday?

  • Sandeep Sonawane February 11, 2010, 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.

  • brian June 7, 2010, 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

  • mrevans July 30, 2013, 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

  • Liam Lord May 1, 2014, 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

  • brian May 1, 2014, 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).

  • krishna rao October 2, 2015, 5:23 pm

    Hi
    I am the beginner for script. Can you suggest how to develop scripting skills.

  • kumar October 6, 2015, 7:39 am

    Hi All,

    I need to run cronjob first 3 mondays .I ran below cron it is running daily.My operating system is Redhot linux 6.7.

    cron :
    00 11 1-25 * 1 sh /home/db2inst/test.sh

    Can you please help me any body.

    Regards,
    Kumar

Leave a Comment


   Tagged with: , , , , , , , , ,