Time-based job scheduling in Debian (cron and friends)
Introduction
Time-based job scheduling is integral part of most operating systems. In the UNIX world, this is usually accomplished by a program called cron. Since it's so old, its functions have diverged and developed. Most cron implementations, including the one used in Debian, are based on the ancient Vixie Cron, named for its author, Paul Vixie. Vixie Cron didn't see an upstream release in two decades. Wikipedia says that in 2004, vixie cron 4.1 was renamed to ISC cron, but for historical reasons, Debian's cron has stayed based on Vixie cron 3.0pl1 up to today.
A multitude of enhancements and accompanying software has surfaced, and time-based job scheduling is today one of the places where different Linux distributions do actually still differ from each other. This article tries to summarize the situation and was motivated by a short debian-devel thread about the current state of affairs. This Wiki Page is rather new (written on 2019-07-24). Feel free to point out errors and fix them.
Chapter 9.5 of the Debian Policy Manual gives additional input.
crontabs
A Debian system has the following cron tab files and directories:
- /etc/crontab, usually only holding entries to run the jobs from /etc/cron.{daily,weekly,monthly}. Packages MUST NOT touch this file according to Policy.
- /var/spool/cron/crontabs/, holding a crontab per user. These crontabs usually get maintained via the crontab(1) tool. root's "personal" crontab is a great place to hide jobs you will never find again.
- Files from /etc/cron.d/ are considered as additions to the global /etc/crontab and treated the same. This allows both packages and the local administrator to drop in system-wide cron jobs without having to modify /etc/crontab. This, for example, is a Debian addition and not supported in plain Vixie cron (should you still find one).
The directories /etc/cron.{daily,weekly,monthly} contain scripts (not crontabs!) that get executed sequentially in lexical sort order via run-parts from /etc/crontab in the respective intervals. It is currently unknown whether there are packages that depend on the lexical sort order of cron jobs to be executed.
Software currently in Debian
Package maintainers of cron-related software, please feel free to add a section about your software. The list given here is most probably incomplete and omission doesn't imply an opinion.
cron
This is the cron package that gets installed on Debian systems if the local admin does not explicitly install a different one. It's a heavily patched Vixie Cron 3.0pl1 and has been this way since Debian's beginning, the first changelog entry being 3.0pl1-35 from 1996. For example, an @reboot time has been added to allow processes to run after the system was brought up. The man page for the daemon, cron(8), lists all of Debian's enhancements in the DEBIAN SPECIFIC section.
If a system is not up and running at the time a cron job is scheduled to run, the job is not executed, which makes this version of cron hard to use on personal machines that get turned off or sent to sleep at night. This is also a challenge for a server that crashed at night and gets rebooted on the next day.
Any standard output and standard error output of a cron job executed by cron is e-mailed to the address that the MAILTO variable in the crontab points to. However if the package is built with DEB_BUILD_OPTIONS=debug then all output will also go to STDERR. See [here](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=887035#15) for instructions.
A plain cron installation in Debian runs the daily cron job at 06:25, the weekly ones at 06:47 and the monthly ones at 06:52.
The cron package is currently maintained in the Debian project on salsa by a small team, but does only get the minimum of maintenance.
It is also planned to organize the migration from cron/anacron to cronie on a mailing list (not yet created). See "Future Developments" below.
anacron
Anacron is the canonical way to run at least the jobs from /etc/cron.{daily,weekly,monthly) after startup, even when their execution was missed because the system was not running at the given time. Anacron does not handle any cron jobs from /etc/cron.d, so any package that wants its /etc/cron.d cronjob being executed by anacron needs to take special measures.
If anacron is installed, regular processing of the /etc/cron.d{daily,weekly,monthly} is omitted by code in /etc/crontab but handled by anacron via /etc/anacrontab. Anacron's execution of these job lists has changed multiple times in the past:
- In wheezy and earlier, anacron is executed via init script on startup and via /etc/cron.d at 07:30. This causes the jobs to be run in order, if scheduled, beginning at 07:35. If the system is rebooted between midnight and 07:35, the jobs run after five minutes of uptime.
- In stretch, anacron is executed via a systemd timer every hour, including the night hours. This causes the jobs to be run in order, if scheduled, beween midnight and 01:00, which is a significant change to the previous behavior.
- In buster, anacron is executed via a systemd timer every hour with the exception of midnight to 07:00 where anacron is not invoked. This brings back a bit of the old timing, with the jobs to be run in order, if scheduled, beween 07:00 and 08:00. Since anacron is also invoked once at system startup, a reboot between midnight and 08:00 also causes the jobs to be scheduled after five minutes of uptime.
anacron also didn't have an upstream release in nearly two decades and is also currently orphaned in Debian.
As of 2019-07 (right after buster's release) it is planned to have cron and anacron replaced by cronie.
cronie
Cronie was forked by Red Hat from ISC Cron 4.1 in 2007, is the default cron implementation in Fedora and Red Hat Enterprise Linux at least since Version 6. cronie seems to have an active upstream, but is currently missing some of the things that Debian has added to vixie cron over the years. With the finishing of cron's conversion to quilt (3.0), effort can begin to add the Debian extensions to Vixie cron to cronie.
Because cronie doesn't have all the Debian extensions yet, it is not yet suitable as a cron replacement.
cronie is currently only in Debian experimental, and also maintained inside Salsa's Debian project. The current plan is to switch from Vixie cron 3.1 to current cronie during the bullseye release cycle, so that bullseye can release with a current cronie replacing the ancient software combination.
systemd timers
Systemd timers are a totally different method for time-based process scheduling. The biggest difference is that systemd timers run independently to each other, probably causing all timers to fire simultaneously unless features like ?RandomizeDelaySec is used, and the jobs run in random order. The output of a systemd timer is not e-mailed, but goes into the journal.
There is a compatibility layer called systemd-cron which comes as a systemd generator building timer units from the crontab files, but the semantics are rather different and it looks like there are no plans to change that.
It will generate individual, parallel timer units for scripts in /etc/cron{d,hourly,daily,weekly,monthly}.
Before Trixie, it would use ""run-parts"" to run the jobs in /etc/cron{hourly,daily,weekly,monthly} sequentialy.
It is unlikely that systemd timers will ever be a drop-in replacement for the old-fashioned cron. Packages are free to migrate from cron to systemd timers, but there cannot be a "big bang" time when all cron jobs get replaced by systemd timers without dedicated action by the individual package maintainers.
bcron
mcron
out of scope
There is also atd which is used to execute a process a single time based on time.
how you can help
Since the plan is to migrate to cronie, if you want to help there are the following things that can be done:
merge Infos from the Cron in here. There's lots of Debian specific interesting information there.
- port features that Debian's cron has, but cronie is missing from cron to cronie. Since both Debian's cron and cronie are forks of the original cron, they should be somewhat compatible. Also Debian cron has now split off its diff from the original cron into patches under debian/patches. So in theory it should be possible to take one patch after the other, see what feature it implements and port it over to cronie.
- once the port is done you could submit that patch upstream with the accompanying rationale that this feature is needed for Debian in order to be able to migrate to cronie.
also Debian's cronie Salsa repo can be forked, a feature branch can be created carrying the ported patch and a pull request can be submitted to Debian's main Salsa cronie repo.
* go through cron's bugs page and see which of those bugs are fixed in cronie and comment inside the bugreport. Possibly it'd be useful to create a tag "implemented-in-cronie" or such, so that they can see at a glance, which bugs would be automatically closed by cronie.
how you can help systemd-cron
If you prefer systemd-cron and want to remove the useless noise of legacy .timer / .service firing up to then do absolutely nothing; you can file a bug against systemd-cron to add your package to the existing heuristic tables. If it's 1-1 perfect match, it's not needed.
The tables are visible there: https://wiki.debian.org/systemd-cron
You can also go through cron-daemon-common's bugs page, fixing those would benefit all "cron" implementations.