Crontab – Schedule First Wednesday Followed by First Monday

cronlinux

Looking to execute a script on the first Monday of the month, then a different script on the first Wednesday of the month.

The issue is that if a new month starts on a Tuesday, for example, then the "first Wednesday of the month" action will hit first. I'd like to have this configured so that the "first Wednesday of the month" action only occurs if it follows a Monday within that month.

Logic can be used to figure this out from a scripting perspective, but the problem is that I need this in a cron expression since that is the only way I can schedule this in the system I am using (it requires a cron expression for advanced scheduling, and details of this system is not relevant to this question).

Edit: There is no dependency or relationship between the aforementioned scripts being executed by cron. For the sake of simplicity for the question, they would simply be two separate cronjobs in the same crontab.

Best Answer

In order to run a command on the first Monday of a month, I would suggest this crontab line, initially:

# m h d o w u cmd
0 3 1-7 * 1 root /usr/local/sbin/kachow

Because the week day of the 8th month day is definitely the same as of the 1st month day, a crontab line specifying both the first seven days of the month and Monday is expected to achieve initial intention, isn't it?

Unfortunately, that crontab line is wrong. Actually, the kachow script would then run everyday on the first seven days of each month and also on every Monday. crontab uses an OR logic to combine days of month and days of week. The crontab (5) manual page provides the following note:

Note: The day of a command's execution can be specified by two fields - day of month, and day of week. If both fields are restricted (ie, aren't *), the command will be run when either field matches the current time. For example, "30 4 1,15 * 5" would cause a command to be run at 4:30 am on the 1st and 15th of each month, plus every Friday.


The logic needs to be defined in the command part of the crontab line too in order to restrict command execution to the first Monday of the month. Therefore, either one of the following lines will work as expected:

# m h d o w u cmd
0 3 1-7 * * root [ $(date +%u) -eq 1 ] && /usr/local/sbin/kachow
# m h d o w u cmd
0 3 * * 1 root [ $(date +%-d) -le 7 ] && /usr/local/sbin/kachow

Similarly, a script expected to run on the first Wednesday of a month only if following a Monday within the same month may be scheduled by one of the crontab lines below. I believe the 8th and 9th days of the month should be excluded from the logic; on the contrary case, woof-woof script would run unexpectedly on the second Wednesday of the month.

# m h d o w u cmd
0 3 3-7 * * root [ $(date +%u) -eq 3 ] && /usr/local/sbin/woof-woof
# m h d o w u cmd
0 3 * * 3 root [ $(date +%-d) -ge 3 -a $(date +%-d) -le 7 ] && /usr/local/sbin/woof-woof
Related Topic