4 ms·
Obviously you can do additional time & date checking in a shell wrapping the script or binary cron ultimately runs, just as you could do the time & date checkin
by harshreality 4mo ago
Obviously you can do additional time & date checking in a shell wrapping the script or binary cron ultimately runs, just as you could do the time & date checking in the script or binary itself. That's far more complex.
Systemd enables cleaner, simpler syntax for common cases. Instead of "59 23 * * *", simply "23:59". Instead of "0 0 * * sun[day]", simply "sun[day]". 1st of the month and don't care exactly what time? Instead of "0 0 01 * *", simply "*-*-01".
Systemd started with the principle that they wanted to accept ISO8601 timestamps, then extended that with lists, increments, ranges. They developed that into a superset of basic cron capabilities, while maintaining similar syntax as best they could for increments and lists; they diverged for ranges and nth-from-last because those conflicted with the - date separator. They repurposed the little-used ~ cron randomization operator in the process. (systemd uses a separate RandomizedDelaySec line for that, which is also arguably superior because it randomizes per trigger, not on initial load of the timer)
The alternative is how AWS does it. They have separate cron() and at() syntax. at() takes timestamps. cron() takes cron+quartz syntax, mangled to remove seconds. They also have rate(value units), because apparently cron syntax is too complicated for most people. I'm sure in theory they did it to support "every 7 minutes" cases. I bet if you surveyed actual rate() AWS schedules, 99% would be cases that evenly divide a larger time unit, and could therefore be implemented with cron().
Cron syntax is more of a mess than I thought. While basic system crons don't support any advanced features, AWS and Cloudflare have adopted LW# capabilities, derived from quartz job scheduler syntax (Cloudflare references quartz explicitly). Quartz has extra fields for seconds and year (year optional, so it must go last, which breaks d m Y sequencing) so its syntax has 6 or 7 fields vs the standard 5. CF uses 5 fields, no seconds or years. AWS uses 6 fields, years but not seconds. Whenever you interact with cron-derived systems, you have to remember not just whether they support quartz-style syntax, but whether they support seconds and/or years. Is that really simpler?
The one feature I found interesting, "W", may not work the way I anticipated according to quartz's documentation. I thought "nearest weekday to the 1st of the month" might be useful because it maps to some billing cycles, but quartz (at least through 2.3) couldn't do that. The 2.3 docs say that 1W, if the 1st falls on a Saturday, triggers on the 3rd because it won't jump backwards over a month boundary. That was my only interesting use case for "W". Systemd does everything else, though it requires more verbosity in some cases, it's simpler in many others. 2.4/2.5 are from the last couple of years, and their docs are restructured and don't mention that, so maybe it was finally fixed? I'm not about to install java crud to test.
I didn't find the *-*~01 syntax that strange (last day of every month). The "fri *-*~07/1" syntax for "last friday of every month" is what I found magical, but it makes sense now that I've thought about it more.
What would you prefer for 3rd friday of the month? Cron (5-field, quartz syntax)
0 0 ? * fri#3 (special syntax is needed because cron uses logical-or to combine day and weekday fields)
or systemd
fri *-*-15..21 (works because systemd day and weekday are joined with logical-and)
[cf] https://developers.cloudflare.com/workers/configuration/cron-triggers/ https://developers.cloudflare.com/workers/configuration/cron...
[aws] https://docs.aws.amazon.com/scheduler/latest/UserGuide/schedule-types.html* https://docs.aws.amazon.com/scheduler/latest/UserGuide/sched...
- simoncion 4mo ago> Systemd enables cleaner, simpler syntax for common cases. I disagree. It's all a matter what you're accustomed to. On top of that, what's at least as important as clear syntax for simple cases is the establishing of a handful of rules that well serve both the simple and complex cases. Consistency that leads to complicated cases being made easy should not be avoided just to make the simple cases extremely welcoming to the newcomer. Note that I'm not saying that 'systemd-crond' falls into this trap, but I am saying that oh so many tools that aim to be "approachable by newcomers" enthusiastically throw themselves into it. > Cron syntax is more of a mess than I thought. Nah. It's just there are a very large number of cron implementations. If The Systemd Project were actually a thing that people could make an independent reimplementation of, we'd see at least as much inconsistency in 'systemd-cron' scheduling syntax as people extended it in their reimplementations to meet their needs. > What would you prefer for 3rd friday of the month? Cron (5-field, quartz syntax) I don't understand why the "day of month" column has a "?" instead of a "*", and I don't understand why "fri#3" isn't rendered as "Fri/3", but whatevz. I prefer that to the systemd syntax. FWIW, I think you can directly translate your systemd scheduler line into this for most crons: * * 15-21 * Fri Edit: Oh, no, you cannot. From crontab(5) Note: The day of a command’s execution can be specified in the following two fields — ’day of month’, and ’day of week’. If both fields are restricted (i.e., do not contain the "*" character), 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. Hm... Yeah, the handling of the "day of week" column is a terrible wart on the rules.
- harshreality 4mo agoI think you're talking about syntactic simplicity. Systemd requires three field separators (space, :, -) because that's how ISO8601 dates are written. That means not all fields will be space separated, which may be more challenging to visually parse. It's not going to look as clean. Is that what you mean? Everything else is simpler. You don't have to count fields to figure out whether you're dealing with a day vs a month, or an hour vs minute, no matter how the fields are aligned or how long or complex they are. You can scan left and right and look for space and dash and colon to figure out where you are. The formats for time and date are distinctive and ubiquitous. You don't have to guess what you're looking at when you just see one of them in isolation. Very little follows from cron's format. You have to learn which fields are which for your particular implementation: does it include seconds? You have to learn the bizarre interaction between day and weekday, to do something non-trivial with them. You have to carefully keep track of which field you're in because you can't determine that from neighboring syntax. The visual clutter, if you want to call it that, of systemd's iso8601-based syntax only applies if you're doing complicated rules. In the vast majority of cases it would simply be an ISO8601 timestamp with various values replaced with *'s, and at most one /. That first impression you had is what I thought too, before diving into it for my previous replies. But no, cron logic is that day and weekday are ORed. It lets you do clever things like run a script on the 1st and 15th of every month, AND on mondays, all in one line. I don't think I've ever seen such a thing in the wild. I'd go so far as to say it's stupid, because it's likely to be misinterpreted if anyone did use it that way. All the other fields are ANDed. I would say that systemd's AND logic is better... and more consistent, which is your own acceptance criterion.