runwhen overview

The biggest difference between runwhen and other schedulers is that runwhen doesn't have a single daemon overseeing multiple jobs. The runwhen tools essentially act as a glorified sleep command. For each job you want to schedule, you run a command (typically scripted) that:

If a job is to run periodically, you'll configure it to run under a respawner such as supervise or init. (You could instead let the job itself end by re-executing the command line to reschedule itself, but a respawner would protect against crashes.) One-time jobs can be run in the background from your shell.

One program, rw-sleep, does the sleeping. The other tools in the package compute timstamps according to various criteria. You can develop your own tools to compute timestamps according to any criteria that may be of interest to you, and use those to control the duration of rw-sleep's sleep.

Rationale: why not cron/at/etc.?

When I posted this project to Freshmeat, one of the Freshmeat maintainers asked me "What does this do that isn't already supported by the 'at' command?". The following is a revision of my response; many of these comments apply equally to cron, fcron, anacron, and other schedulers.

Perhaps runwhen does nothing that at doesn't, and there are lots of things at does that runwhen doesn't. For example, runwhen doesn't change user IDs - thus it will never run anything as the wrong user. It doesn't keep a central daemon running at all times - thus it won't break if that daemon dies, and it doesn't require any modifications to the system boot procedure. It doesn't log through syslog - thus it won't make a mess on the console if syslogd isn't running. It doesn't centralize storage of scheduled jobs (or any other per-job information) - thus unprivileged users can install and use it without cooperation from root, and without the use of a setuid program to handle changes. It doesn't send output through mail - thus it doesn't break if there is no mail system installed. It doesn't check access control files - thus it doesn't gratuitously deny users the simple conveneince that is the only difference between itself and:

(sleep 1234 && do-some-command) &

But actually, there are some things runwhen does that at doesn't. You can interrupt its sleep and execute the job early by sending SIGALRM. You can have it wait indefinitely until SIGALRM. For cron-like jobs that run repeatedly, you can place an upper bound on the amount of time between runs, in case the system was off during the last scheduled run time, like anacron. If a job takes longer to run than the period between scheduled run times, then you can control on a per-job basis whether to wait for the previous run to finish or to run multiple instances concurrently. You can schedule as many jobs as you like, up to the kernel's maximum number of processes, instead of an arbitrary limit compiled into the scheduler. You can develop and use your own tools to modify the sleep duration, based on criteria I haven't thought of.