logoalt Hacker News

jeroenhdyesterday at 3:22 PM3 repliesview on HN

Having had to work on an application supposedly supporting cron expressions: the numbers are just the basic parts of the language.

When someone inputs something ridiculous like "5,3/4 4-8,11 1 4,5,6,9-11 */2" you get to enjoy the fun of reverse engineering what they meant (it's never what they actually wrote).

And that's before you get to all the extensions supported in some cron environments (but not all).

I find systemd timers a lot more manageable. Things like having control over whether or not long-running jobs are allowed to overlap and the ability to run tasks between start-finish rather than a fixed time window are major improvements for me. At some point my VPS went down because the backup job ran into some kind of symlink loop and cron just kept spawning more and more backup tasks even though none of them finished.

Having to re-write commands and scripts because CRON had its own special PATH was also a pain point, but the same can be true for some types of systemd timers. But: you can execute those timers manually if you want instead of updating the crontab to trigger in 30 seconds and simply waiting.


Replies

thomashabets2yesterday at 5:51 PM

Per other comments though, it looks like systemd's syntax when you want to specify something that's not just that one number is at least as complex.

Is your example (which I agree, looks cryptic) any less cryptic in systemd?

I asked jippity, and it said this:

    [Timer]
    OnCalendar=*-04,05,06,09,10,11-01 04..08,11:03/4,05:00
    OnCalendar=Sun,Tue,Thu,Sat *-04,05,06,09,10,11-* 04..08,11:03/4,05:00
To which I have to go: "what?"

> Things like having control over whether or not long-running jobs are allowed to overlap

With cron that's just prefixing the command with `flock -n <lock>`, but sure the "pick somewhere to put the lock" is probably better with systemd.

> Having to re-write commands and scripts because CRON had its own special PATH

Why? Wouldn't you just put that in the crontab? I don't even see this as different. It's in the cron config or the systemd timer config.

The other improvements you mentioned seem good.

show 1 reply
ink_13yesterday at 3:32 PM

> 5,3/4 4-8,11 1 4,5,6,9-11 */2

What's so hard about "At 5 minutes past the hour and every 4 minutes, starting at 3 minutes past the hour, at 04:00 AM through 08:59 AM and 11:00 AM, on day 1 of the month, every 2 days of the week, only in April, May, June, and September through November"?

(I used https://crontab.cronhub.io/ to decode it, to be fair)

networkedyesterday at 3:42 PM

Complex expressions are one of the things I don't like in cron. On Debian/Ubuntu servers, I just bite the bullet with systemd timers. On my workstation, I have a personal job scheduler that feels easier and more fun to tinker with. The scheduler uses Starlark functions instead. For example:

  # Run if at least a day has passed since the last run
  # and it isn't the weekend.
  def should_run(finished, timestamp, dow, **_):
      return dow not in [0, 6] and timestamp - finished >= one_day
This was inspired by GNU mcron. In mcron, jobs can calculate the next time they should run using Guile (https://www.gnu.org/software/mcron/manual/mcron.html#Guile-S...):

  (job
     '(next-minute-from
        (next-hour (range 0 24 2))
        '(15))
     "my-program")
I found mcron's scheduling counterintuitive and decided I wanted a function that returned a boolean. I can tentatively recommend it.