The cron scheduler has been a useful tool for Linux and Unix admins for decades, but it just might be time to retire cron in favor of a more modern design. One replacement, still in heavy development, is whenjobs. This weekend, let’s take a look at whenjobs and see what the future of scheduling on Linux might look like.
The default cron version for most Linux distributions these days is derived from Paul Vixie’s cron. On Ubuntu, you’ll find the Vixie/ISC version of cron. On Fedora and Red Hat releases you’ll find cronie, which was forked from Vixie cron in 2007.
You can also find variants like fcron, but none of the variants that are around today have really advanced cron very much. You can’t tell cron “when this happens, run this job.” For instance, if you want to be notified when you start to run low on disk space, or if the load on a machine is above a certain threshold. You could write scripts that check those things, and then run them frequently. But it’d be better if you could just count on the scheduler to do that for you.
There’s also the less than friendly formatting to cron. When I’ve worked in hosting, I found plenty of cron jobs that were either running too often because the owner mis-formatted the time fields, or that didn’t run as often as expected for the same reason. Back up jobs that should have been running daily were running once a month. Oops.
Red Hat’s Richard W.M. Jones has been working on whenjobs as “a powerful but simple cron replacement.” The most recent source tarball is 0.5, so we expect that it’s starting to be usable but still has some bugs. (And it does, more on that in a moment.)
A slight word of warning, you’re probably going to need a lot of dependencies to build whenjobs on your own. It doesn’t look to be packaged upstream by any of the distros, including Fedora. It also requires a few newer packages that you’re not going to find in Fedora 16. I ended up trying it out on Fedora 17, and installing a slew of OCaml packages.
To get whenjobs, you can either grab the most recent tarball or go for the most recent code out of the git repository. You can get the latest by using
git clone git://git.annexia.org/git/whenjobs.git but I’d recommend going with the tarball.
Jones recommends just building whenjobs with
rpmbuild -ta whenjobs-*.tar.gz. (Replace the * with the version you have, of course.) If you have all the dependencies needed, you should wind up with an RPM that you can install after it’s done compiling.
To use whenjobs, you’ll need to start the daemon. Note that you don’t start this as root, you want to run it as your normal user.
According to the documentation, you want to start the daemon with
whenjobs --daemon, but Jones tells me this isn’t implemented just yet. Instead, you’ll want to run
/usr/sbin/whenjobsd to start the daemon. You can verify that it’s running by using
pgrep whenjobsd. (Eventually you’ll be able to use
To start adding jobs to your queue, use
whenjobs -e. This should drop you into your jobs script and let you start adding jobs. The format is markedly different than cron’s, so let’s look at what we’ve got from the sample whenjobs scripts.
every 10 minutes : << # Get free blocks in /home free=`stat -f -c %b /home` # Set the variable 'free_space' whenjobs --type int --set free_space $free >> when changes free_space && free_space < 100000 : << mail -s "ALERT: only $free_space blocks left on /home" $LOGNAME </dev/null >>
Jobs start with a periodic statement or a when statement. If you want a job to run at selected intervals no matter what, use the
every period statement. The period can be something like
every day or
every 2 weeks or even
every 2 millenia. I think Jones is being a wee bit optimistic with that one, but on the plus side – if whenjobs is still in use 1,000 years from now and it doesn’t run your job, Jones probably won’t have to deal with the bug report…
Otherwise, you can use the
when statement to evaluate an expression, and then perform a job if the statement is true. See the man page online for all of the possible when statements that are supported.
As you can see, you can also set variables for whenjobs. It accepts several types of variables, such as ints, strings, booleans, and so forth. You can see and set variables using
whenjobs --variables or
whenjobs --set variable.
The script for the job is placed between brackets (
<< >>). Here you can use normal shell scripts. The scripts are evaluated with the $SHELL variable or
/bin/sh if that’s not set. Presumably you could use
zsh instead if you prefer those.
If you want to see the jobs script without having to pop it open for editing, use
whenjobs -l. You can use
whenjobs --jobs to see jobs that are actually running. If you need to cancel one, use
whenjobs --cancel serial where the serial number is the one given by the
whenjobs --jobs command.
A cron Replacement?
I don’t think whenjobs is quite ready to be rolled out as a cron replacement just yet, but it’s definitely worth taking a look at if you’ve ever felt frustrated with cron’s limitations. It will probably be a while before whenjobs starts making its way into the major distros, but if you’re feeling a little adventurous, why not start working with it this weekend?