Whenjobs: The Simpler Alternative to cron

Cron jobs are essential to managing Linux and Unix systems; however, the syntax is limited and prone to errors. A modern cron substitute – Whenjobs – sets out to remove these weaknesses.

One of the many heirlooms from early Unix (since V7 Unix to be exact) is the cron daemon, which still runs regular jobs on today’s Linux and BSD systems. Although some alternatives to cron have since been developed, such as fcron [1] and anacron, the principle itself has barely changed.

Red Hat programmer Richard W.M. Jones has now broken with tradition and come up with a new cron alternative – a project called Whenjobs. Basically, Whenjobs offers two advantages to cron: simpler syntax for defining jobs and execution times and a system that allows users to define dependencies between jobs.

Prebuilt Whenjobs packages are already available for Fedora 17, but users of other distributions will have to build the tool themselves. To install, you can check Whenjobs out from the Git repository. However, it is easier to download the latest tarfile, because then you don’t have to do battle with autoconf and automake.

Because Whenjobs is written in the functional programming language, Ocaml, you will need the matching compiler and a few packages. You can install these with the following command, for example, on Ubuntu 12.10:

sudo apt-get install ocaml ocaml-findlib libcalendar-ocaml libcalendar-ocaml-dev camlp4-extra libocamlnet-ocaml-bin

The ./configure command starts the configuration step, which tells you whether all the necessary packages are installed. During testing, I saw the following error when I ran make: error: Unbound value XDR.safe_add. I resolved this by deleting the generated files lib/whenproto_aux.ml and lib/whenproto_aux.mli. Calling make install installs Whenjobs globally on the system.

Startup Aid

When launched with the --help option, whenjobs outputs a short help text, listing the available options and parameters (Figure 1).

Figure 1: When launched with --help, Whenjobs displays the available command parameters. Detailed help is available via the man page.

The command whenjobs -e tells the program to launch an editor, which comes up with a Whenjobs file, although it only contains a comment (Figure 2). The vi editor in the figure shows this to be the .$HOME/whenjobs/jobs.ml file.

Figure 2: When you first start Whenjobs, it comes up with a job that displays a brief help text.

In the case of syntax errors in the jobs file, Whenjobs is not very helpful; in fact, it simply outputs a compiler error message, although it still saves the file. Instead of a file, you can also store several files with the .ml extension in .whenjobs; however, you will then need to edit them manually. Additionally, the file names have to obey Ocaml rules; for example, they are not allowed to contain hyphens.

The basics of Whenjobs files are explained in this comment. Comments start with (* and end with *) – this is a subtle hint that Whenjobs files themselves are Ocaml files – however, you don’t normally need to worry about the programming language when you use Whenjobs. A time starts with the every keyword and ends with a colon, for example:

every 10 minutes:

The characters << then introduce a block of shell commands, which is terminated by the >> characters.

Variables

The example in the comment in Figure 2 illustrates some Whenjobs features, such as setting variables. To do this, the tool offers the --set option, which you can extend by indicating the variable type (--type). The following code thus runs the stat command first and assigns the results to the free shell variable. The second line reads this variable and assigns it to the Whenjobs free_space variable as an integer; the latter is then available to other jobs.

free=`stat -f -c %b /home`
whenjobs --set --type int free_space=$free

The lower code segment in Figure 1 shows how to execute new jobs with Whenjobs, depending on certain conditions. The syntax for this is:

when  : 

For example, the Whenjobs changes function lets you monitor when a variable changes. Using the above variables, you can thus formulate a condition such as “if free_space changes and if the value is less than 10,000 (blocks)”:

when changes free_space && free_space < 100000 :

For this to work, the Whenjobs daemon (whenjobsd) must be running; the daemon stores the variables and executes the jobs. It can be started using the whenjobs front end and the --daemon-start option. Alternatively, you can also start whenjobsd directly; then, you can use the -f option to prevent the daemon from running in the background and the -d option to turn on debug messages. The whenjobs --variables command tells the tool to output the list of currently stored variables.

If you do not want a change to a variable to trigger a change event, you can additionally set the --whisper option:

whenjobs --set free_space=0 --whisper

Whenjobs shows you which jobs are active when you stipulate the --jobs parameter and which jobs are loaded when you use the --job-names parameter. You can set the name by adding it before the line that begins with a when or every:

job "disk monitoring"
every 15 minutes :

You can run individual jobs manually by typing whenjobs --start jobname. Active jobs can be canceled by typing whenjobs --cancel <number> – using --jobs shows the number, and typing:

whenjobs --tail 

will show you the output from an active job.

Millennium Proof

When it comes to defining times for scheduled jobs, the tool offers a whole range of options: second, minute, hour, day, week, month, year, and even decade, century, and millenium [sic]. These options can be combined with every or with a number: For example, every hour runs a script once an hour, and every 15 minutes runs a script every 15 minutes.

Whenjobs also offers a wealth of expressions: They can be linked with logical and (&&) and or (||) operators and also negated. Comparisons of two expressions with various combinations of greater than, less than, and equals signs can be numerical or based on string comparisons.

Other built-in functions can compare variables with their previous values or determine whether a value increases or decreases. Also, users can program their own expressions in Ocaml. More information about this is available in the detailed man page provided by the tool.

Mature

Whenjobs was developed as a solo project by Jones as a replacement for cron. Whenjobs offers simpler syntax and supports dependencies between jobs. In a blog posting, Jones expressly points out that this is a private project and is not planned as a replacement for the standard cron system used by Fedora or Red Hat. However, he does use the work for automated builds of virtualization tools on Red Hat, thus demonstrating its capability for production use.

Info

[1] “Fcron” by Matija Suklje, Linux Magazine, January 2010, pg. 48