Wednesday, May 8, 2013

Unix: Timing your cron jobs

Most of my Unix admin cronies cut their teeth on tools like cron. There is nearly nothing as fundamentally essential to administering Unix systems are writing scripts and then setting them up to run without intervention. Even so, cron has become more versatile over the decades and there are a lot of nice "tricks" that you can use to tailor your cron tasks to the work you need to do.
The traditional fields are fairly easy to remember -- as long as you can keep in mind that the smallest time unit that you can address is minutes and that the fields go from small units (minute) to large (month) until you hit the day of week field. I still often tick off the time fields on the fingers of my left hand. Let's see ...
            .'`  __/_______ minute after the hour (0-59)
        ---'  -'`    ______) hour of the day (0-23)
                     _______) day of the month (1-X where X depends on the month)
                    _______) month of the year (1-12)
        -----..___________)   day of the week (0-6)
And, of course, an * in any of these time fields to mean "any" of the legitimate values
As an example, this cron taks would run every 15 minutes after the hour:
15 * * * * /usr/local/runtask
Easy enough! But there are many options that make scheduling tasks to run very frequently or very infrequently even easier.
For one thing, you can tell cron to run a process multiple times an hour, multiple times within a day, or even multiple times in a week by selecting two values and separating them with a comma. The value 6,18 in the hour field, for example, might tell cron to run a task at 6 AM and 6 PM:
0 6,18 * * * /usr/local/runtask
where this one would tell cron to run the process at 6:15 AM, 6:45 AM, 6:15 PM and 6:45 PM:
15,45 6,18 * * * /usr/local/runtask
You can also tell cron to run your tasks over a range of values -- such as Monday through Friday (and not on the weekends) or from 8 AM to 6 PM as shown here:
0 23 * * 1-5 /usr/local/weekdays
0 8-18 * * 1-5 /usr/local/workhours
And, while I've seen numerous instances of "0,15,30,45" used to run a job every 15 minutes, the */15 specification does the same thing and is neater and easier.
I was also quite surprised when I first noticed that the strings sun, mon, tue, wed, thu, fri and sat also work for the day of the week field. I've become so used to 0-6 that I sometimes refer to Saturdays as "day 6" and confuse my friends.
Linux systems also provide some very useful shorthands for running tasks at infrequent intervals. Instead of the five time fields shown above, you can use any of these:
@yearly runs on January 1st at zero at 00:00 (equivalent to 0 0 1 1 *)
@monthly runs on the first of every month at 00:00 (equivalent to 0 0 1 * *)
@daily runs at the beginning of every day (equivalent to 0 0 * * *)
@hourly runs every hour (equivalent to 0 * * * *)
@reboot runs when the system boots
These top four options are very handy as long as you're happy to run your tasks at 00:00. Otherwise, you need to
set your time values using the typical five fields.
Cron allows you to run a task as frequently as once a minute and as infrequently as once every 6-7 years (e.g., if you run a process at 6 AM on the 13th of May only if it's a Friday).
* * * * * /usr/local/everyminute
10 10 13 5 5 /usr/local/almostnever
Anther useful thing to know in case you're new to cron is that, by setting your EDITOR environment variable, you can tell crontab -- the command you must use to edit or display your cron tasks -- which editor you want to use to set up your cron tasks. This will normally default to vi.

No comments:

Post a Comment