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


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 on First Monday at 11:30:
30 11 1-7 * Mon [ "$(date '+%a')" == "Mon" ] && /path/to/

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:

🐧 If you liked this page, please support my work on Patreon or with a donation.
🐧 Get the latest tutorials on SysAdmin, Linux/Unix, Open Source & DevOps topics via:
CategoryList of Unix and Linux commands
File Managementcat
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network Utilitiesdig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04
17 comments… add one
  • kumar Oct 6, 2015 @ 7:39

    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/

    Can you please help me any body.


  • krishna rao Oct 2, 2015 @ 17:23

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

  • brian May 1, 2014 @ 18:17

    @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).

  • Liam Lord May 1, 2014 @ 15:41

    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

  • mrevans Jul 30, 2013 @ 16:47

    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


  • brian Jun 7, 2010 @ 23:41

    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/

    Thanks for the great tip

  • Sandeep Sonawane Feb 11, 2010 @ 5:19

    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.

  • Eric Feb 10, 2010 @ 18:27

    What is the syntax to run it every other Monday?

  • James Sep 10, 2008 @ 22:27

    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.

  • radar Aug 2, 2008 @ 5:31

    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.

  • Alan Mar 22, 2008 @ 2:00

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

    50 23 * * * lynx -dump

  • thegetpr Mar 12, 2008 @ 13:03

    how to add php script to cron job

  • Nilay Dec 6, 2007 @ 6:03

    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.

  • parashar Oct 1, 2007 @ 7:31

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

  • SREEKUMAR Sep 17, 2007 @ 2:04

    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/

  • Scott Carlson Jul 5, 2007 @ 22:00

    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 on First Monday at 11:30:
    30 11 1-7 * * [ “$(date ‘+%a’)” == “Mon” ] && /path/to/

    • Ram Mar 3, 2011 @ 19:32

      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.

      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.


Leave a Reply

Your email address will not be published. Required fields are marked *

Use HTML <pre>...</pre>, <code>...</code> and <kbd>...</kbd> for code samples.