Scheduling tasks is essential for users of modern, complex operating systems. As functionality expands yet the time available to manage the system does not.

To run scheduled jobs Linux and Unix both use a package called cron. There's also an application called at, used for scheduling one-off jobs, but we're more concerned about regular job scheduling here.

To organise your job schedule, you need to edit your crontab file. Unlike Windows, you don't provide the Unix/Linux user ID and password to the job – instead, each user with scheduled jobs has a separate crontab file. Jobs are run under the identity of whoever owns the crontab. So, all jobs in the crontab of user "bob" will be run under Bob's user ID and so on.

The command for editing one's crontab is, imaginatively, crontab. There's a number of variants:

crontab –l: Show the contents of the file crontab –e: Edit the file crontab –r: remove the file (delete all scheduled jobs for this user)

A non-root user can only edit his or her own crontab, but the root user can edit anyone's, using a command of the form crontab –u bob –e.

Each job in a crontab is a single line, of the form:

X X X X X /path/to/script

The rightmost component is, fairly obviously, the name of the script that's to be run – remember to provide the full pathname as cron doesn't know anything about where your home directory is. If the program or script you're running requires parameters, you just put these after the command, just as you would if you were running it by hand on the command line.

The five elements on the left dictate the schedule for the job, and represent, in order:

Minute (0-59) Hour (0-23) Day of month (1-31) Month (1-12) Day of week (0-6, where 0 is Sunday)

Each field can be defined as a selection of several items, so you can define complex schedules. Multiple entries are denoted by separating numbers with commas (e.g. 3,6,9,12), while ranges are denoted by separating a pair of numbers with a hyphen (e.g. 6-12 means the same as 6,7,8,9,10,11,12). You can, actually, have a set of ranges (e.g. 3-6,9-12 equates to 3,4,5,6,9,10,11,12).

The final modification we can make is to replace any or all fields with a *, which means "all possible values for this field". So if we put a * in the Hour field, this would mean the same as using 0-23 – except it's less verbose.

Let's try a few examples, as it'll all become clear.

0 * * * *: Once per hour, on the hour (minute 0 of every hour of every day of every month). 0,30 * * *: Twice per hour – once on the hour, once on the half-hour. 0 3 * * *: Every day at 03:00 (minute 0 of hour 3 of every day of every month). 0 3 * * 6: Every Saturday at 03:00 (day 6 is Saturday). 30 9-17 * * 1-5: Every weekday (Mon-Fri) at half past the hour from 09:00 to 17:00 inclusive. 0 6 1 * *: The first day of every month, at 06:00.

The trick with complex crontab timings is to build them up gradually – do each element by itself, start with the numbers, then build the ranges, then bolt them into multiples with commas if you need to.

As with Windows, you need to make sure that cron is running if you're going to expect it to schedule jobs for you. The easiest way to check is to examine the process table, to look for the cron daemon:

merlot:~> ps ax | grep cron 292 ? S 0:15 /usr/sbin/cron

The giveaway is that there's a process with a low-numbered ID (292 in this case) which shows it was probably started at boot time, called either cron or crond. If you don't find anything running, you'll need to enable the cron server by editing the machine's startup files (something we've already discussed in a previous How To).

Finally, it's worth recapping on something we mentioned earlier in passing – namely that cron doesn't know anything about the environment variables that you use when you log in and run scripts in person. So if the program you're trying to run assumes anything about its environment, you'll probably have to write yourself a little wrapper script to set all the environment variables that the program needs – or at the very least ensure that you refer to all files and executables by their full path name.