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.