3

I need to schedule a cron job to run at 3:00 PM on the first Thursday of every month. How can I do this? I have read another topic similar to this, but it is for the first Sunday of every month. How do I modify this to suit my needs? Please do not refer me to any manuals as they are of no help to me. This is why I am asking the question here.

Every first Sunday of very month

00 09 * * 7 [ $(date +\%d) -le 07 ] && /run/your/script

A simple answer should do here, I'm just don't know what the -le 07 stands for.

So the 4 is Thursday, What is the -le 07 in the cron?

is it a check for the first 7th day (Sunday) of the month?

00 15 * * 4 [ $(date +\%d) -le 07 ] && /run/your/script

Or should it be this one?

Assuming this would be a check for the first 4th Day (Thursday) of the month?

00 15 * * 4 [ $(date +\%d) -le 04 ] && /run/your/script

Since English isn't my mother tongue, I hope this is as clear as possible for you guys.

Thanks in advance.

P4R4
  • 53
  • 1
  • 5

3 Answers3

6

the answer:

0 15 * * 4 [ $(date +\%d) -le 7 ] && command

the explanation:

First of all you need to realize that the first Thursday of the month will always have a day of the month that is in the set {1,2,3,4,5,6,7}. That is simply because there are only 7 days in a week. And thus the first Thursday cannot be have a day that is bigger then 7. The same holds evidently for any other weekday such as Tuesday or Saturday.

The command that cron will execute consists of two parts:

  • [ $(date "+\%d") -le 7 ]: This is a simple test that checks if the day of the month is smaller than 7. It essentially checks if we are in the first week of the month. The command date -d "+%d" returns the day of the month as a two-digit number (01,02,03,...,31) and is a string. The test command, here written in an alternative form with square brackets [ ... ] does a check to see if the integer comming from date is smaller then or equal to 7. You can read more on this when typing man test in a terminal.

  • command: this is the command that is going to be executed if the previous test is successful. I.e. if we are in the first week of the month. The reason why this will only execute if the test command is successful, is because of the &&. A command of the form cmd1 && cmd2 will execute cmd1 and only when that one is successful will it execute cmd2.

So since we now have the command, we can now build our crontab file. With a bit more comments (parts starting with #, you can write it as:

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7)
# |  |  |  |  |
# *  *  *  *  *   command to be executed
  0  15 *  *  4   [ $(date +\%d) -le 07 ] && command

The above means, execute the above command at minute 0 of the 15th hour of any Thursday. And since the command contains the test for the first week, it will only run on the first Thursday of the month.

kvantour
  • 25,269
  • 4
  • 47
  • 72
  • @DannyBelanger I understand that it is frustrating when you search for an answer and you don't get it. It is even more frustrating when it takes three days to find it. We all have been there! Also, not understanding the above is not a sign of being dumb; it is an indication that the answer I gave you is unclear. I have now updated the answer and hope that this is more satisfactory. – kvantour Oct 16 '19 at 18:28
  • Thanks for all your comments I have found the answer I was looking for by other means through a Linux developer. Basically, What he said is that I have to run my command every Thursday and in my script, I check if it's the first Thursday of every month if so Run my commands. – P4R4 Oct 17 '19 at 12:28
  • @DannyBelanger I'm glad to hear you found a working solution for you. Be advised that this might be annoying if you want to run your script on a Wednesday from the command-line. It is always good to have a separate script that does this check and calls the original script. – kvantour Oct 17 '19 at 12:48
  • 1
    Believe me, I won't need to run that script on a Wednesday if I do, i'll just duplicate the script and remove the check. – P4R4 Oct 18 '19 at 13:35
2

Why not simply use:

# Example of job definition:
# .---------------- minute (0 - 59)
# |   .------------- hour (0 - 23)
# |   |   .---------- day of month (1 - 31)
# |   |   |   .------- month (1 - 12) OR jan,feb,mar,apr ...
# |   |   |   |  .---- day of week (0 - 6) (Sunday=0 or 7)
# |   |   |   |  |
# *   *   *   *  *   command to be executed
  0  15  1-7  *  4   command

So you tell cron to run at minute 0, hour 15, first 7 days of the mounth, on 4th day (Thursday). It will for sure include only one Thursday, the first one, because in 7 consecutive days of a month it will be for sure only one Thursday and in 7 consecutive days cannot be 2 Thursdays.

0

You can do like this for 2nd Thursday of month:

0 14 /15,/16,/17,/18,/19,/20,*/21 * THU

“At 14:00 on every 15th day-of-month, every 16th day-of-month, every 17th day-of-month, every 18th day-of-month, every 19th day-of-month, every 20th day-of-month, and every 21st day-of-month if it's on Thursday.”

MQQ
  • 1
  • 1