Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
480 views
in Technique[技术] by (71.8m points)

linux - Why crontab uses OR when both day of month and day of week specified?

It is a famous "problem" that when a crontab line contains both day of week and day of month cron uses OR for figuring out a day to fire the command. E.g. if you write

* * 13 * 5 command

the command will execute on every Friday and every 13th day of month, not only on the Fridays that are 13th. This contradicts the format for the other fields (when you write 30 2 * * * it will be executed only when both - hour AND minute - are exactly what you specified; same for all other fields except for DoW and DoM when they are both specified).

So my question is: is there a specific reason for this exception? I mean, there should be a reason, but I can't seem to find it. (And instead I see a lot of people in the internets who would like for these fields to be treated like any other - with the "AND strategy", precisely for stuff like "Friday 13th" or "2nd Thursday of May".)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Going back a step further from Vixie cron, the "wday OR mday" logic was present in System V cron, but not System III or anything earlier.

Before Paul Vixie wrote his cron replacement, BSD cron was like the SysIII-and-earlier cron. All 5 fields were ANDed. The post-4.4 BSDs adopted Vixie cron, making themselves more SysV-like.

So don't ask (blame) Vixie. He was just cloning SysV.

Why did SysV do that? I don't know but I'll try to provide some partial clues...

To try to understand what happened in SysV, it helps to look at the source (before - SysIII and after - SVr4) and also the documentation of the new behavior:

Note: the specification of days may be made by two fields (day of the month and day of the week). If both are specified as a list of elements, both are adhered to.

(Excerpt from SunOS 4.1.3 man page. It appears to be SysV-ish in this area. BSD cron never had this behavior before Paul Vixie wrote his replacement.)

"Both are adhered to" is a confusing substitute for a normal boolean expression using ANDs and ORs. It's still there in the OpenSolaris man page a couple of decades later:

The specification of days can be made by two fields (day of the month and day of the week). Both are adhered to if specified as a list of elements.

The SysV code is a complete rewrite. One of its features is that it sleeps for a long time when no jobs are due to run soon. (The older cron wakes up every minute and compares the current time to all job specifications.) A comment at the top of the calculation function (next_time) explains: NOTE: this routine is hard to understand.

It is indeed hard to understand. It is a "find next execution time for this crontab line" function, instead of a "decide whether the current time matches this crontab line" function, so it takes some effort to even figure out that the matching rule implicit in this function, when both mday and wday are non-*, is (month AND hour AND minute AND (mday OR wday)).

Based on that, combined with the way the documentation avoids explicitly telling us the boolean relationship between mday matching and wday matching, I'm going to guess that the person who wrote the new cron just wasn't thinking about it in those terms. They were thinking not about a combination of 5 booleans (corresponding directly to 5 fields in a struct tm), but about a set of 4 questions:

  1. Is it the correct month?
  2. Is it the correct day?
  3. Is it the correct hour?
  4. Is it the correct minute?

This leads naturally to the day comparisons being combined in their own way before ANDing everything else together. Maybe the SysV cron author just did what felt like the obvious thing at the time, without checking for compatibility with the old cron or pondering use cases like "first Saturday of every month".


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

56.8k users

...