Score:2

crontab date definition for only second Wednesday of the month

cn flag

How do I define crontab date for second Wednesday (of every months) only? I would appreciate your help.

in flag
The cron schedule is too rough a tool for this. You will probably want to use `0 0 * * WED` to run a job every Wednesday, but point to a shell script that validates the week of the month before running a given task.
Soren A avatar
mx flag
I think that 1. Wednesday in a month always will be between day 1 to 7 and so second Wednesday in month must be between day 8 to 14 ... so something like `0 0 8-14 * WED .....` should do it. Off course the two first values (minutes and hour) can be any legal minute and hour value.
cn flag
@SorenA https://crontab.guru/#0_0_8-14_*_wed That runs on day 8 through 14 AND wednesday :) You need a little adjustment: https://crontab.guru/tips.html It probably requires 7 lines `0 0 */8 * WED`, `0 0 */9 * WED`, `0 0 */10 * WED`, `0 0 */11 * WED`, `0 0 */12 * WED`, `0 0 */13 * WED`, `0 0 */14 * WED`
Score:3
jp flag

Cron can not do this natively, but a systemd timer could.

The cron syntax 0 0 8-14 * Wed will not work. It will match every Wednesday as well as every day between the 8th and 14th. As the crontab man page says

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 (i.e., don't start with *), the command will be run when either field matches the current time.

systemd timers handle the logic differently and can do what you want. This syntax would match midnight on the second Wednesday each month.

OnCalendar=Wed *-*-8..14 00:00:00

Links

cn flag
yes cron can do this ;-)
elmclose avatar
cn flag
Thanks Andrew, good links. I can see that cron alone is not enough for this job as I suspected. I also have a job that needs to be done on the last Friday of each month. I will use one of the suggested secondary checks and filter in the correct date.
Score:3
cn flag

You asked for cron so only using cron you can do this using bash's date as a 2nd test:

0   0  8-14 *   *   [ "$(date '+\%u')" = "3" ] && {your script}
  • On every hour of days 8 through 14
  • and then check for wednesday with bash's date. Daynumber 3 is wednesday

The comment from Soren A is a little wrong (BUT the man page is also wrong). 0 0 8-14 * WED = “At 00:00 on every day-of-month from 8 through 14 and on Wednesday.” From the last link:

Tip 1: If the day-of-month or day-of-week part starts with a *, they form an intersection. Otherwise they form a union. * * 3 * 1 runs on the 3rd day of the month and on Monday (union), whereas * * */2 * 1 runs on every second day of the month only if it's also a Monday (intersection). The manpage is incorrect about this detail. More info.

elmclose avatar
cn flag
This is very elegant and compact. I'll try it. Thanks Rinzwind
Andrew Lowther avatar
jp flag
"Tip 1" from https://crontab.guru/tips.html is very interesting. You may want to include it in your answer to support the "man page is also wrong" claim.
cn flag
@AndrewLowther yeah I thought about it at first and decided not to but you are right, so added :+
elmclose avatar
cn flag
Is backslash in [ "$(date '+\%u')" = "3" ] necessary?
cn flag
yes, see `man 5 crontab` "Percent-signs (%) in the command, unless escaped with backslash (\\), will be changed into newline characters, and all data after the first % will be sent to the command as standard input."
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.