Contribute  :  Advanced Search  :  Directory  :  Forum  :  FAQ's  :  My Downloads  :  Links  :  Polls  
AFP548 Changing the world one server at a time.
Welcome to AFP548
Thursday, July 29 2010 @ 09:24 am MDT
   

Crontab Basics

ArticlesOne of the most essential, and misunderstood, server admin skills is being able to maintain a crontab file. The syntax of the crontab file though has been known to drive a sysadmin to drink.

Read on, and never be confused by '30 4 1,15 * 5' again...

Cron and the crontab, the basics:

O.K. here we go. Cron is the name of the program that runs scheduled tasks on your Mac while you are away. It does this by reading a file, called a crontab, once a minute to see what needs to be run and when. There can be several crontab files on the system. By default there is only the system crontab located at /etc/crontab. This file contains things like when periodic runs. Each user on the system can have a crontab file though and that is how you want to run most tasks as you will avoid needing to specify a user or resort to any nasty su tricks.

The crontab format

Although it seems mystical at first, the format for a crontab is actually very simple. It breaks down like this:

minute hour day-of-the-month month day-of-the-week command

Let's look at the five values that make up the time to run section...

For the first three settings you use numbers starting at 0, you can optionally use names for the month and day-of-the-week settings. A '*' is a wildcard that means first-last and matches anything. So let's say we want to schedule a task to run on the hour, every hour.

0 * * * * command

Huh? How does that work? Easy. The 0 minute is the top of the hour. The '*'s match all other possibilities. So it breaks down to minute 0 of every hour, of every day, of every month, every day of the week. Let's look at another one. Let's say I want to run something every Sunday at 12:15 am...

15 0 * * sun command

So I'm telling it run on minute 15, of the 0 hour (midnight), every numbered day of the week, every month, on Sunday. Notice I can use 'sun' for Sunday. I could also use 0 or 7 for Sunday if I felt like it.

Step values and multiples...

So what if I need more flexibility? Never fear, you can use step values and multiples in your crontabs. Let's say I wanted the above example to also run on Tuesday nights.

15 0 * * 0,2 command

Here I used the numerical values for the days, but I could of said 'sun,tue' as well. Note that the day and month names are case-insensitive. Now let's take a look at step values.

If I wanted something to run every two hours I could specify '0,2,4,6,8,10,12,14,16,18,20,22' for the second field but that sucks. Luckily I can use a step value to make this easier and accomplish the same value with '*/2'. So let's say I want to make something that runs every other month on Sundays at 4:32 am...

32 4 * */2 sun command

You can also use a range in place of a list. Rather than type '8,9,10,11' I could just use '8-11'.

Got it? Good!

BSD family perks

Since Mac OS X is BSD based we can use some handy shortcuts. Remember our first example, '0 * * * *' that ran a task every hour? Well, I could also just say

@hourly command

Isn't that nice? You can also use @reboot (On restart), @yearly (0 0 1 1 *), @annually (same as @yearly), @monthly (0 0 1 * *), @weekly (0 0 * * 0), @daily (0 0 * * *), and @midnight (Same as daily). Take a look at man 5 crontab for more details.

Command time

OK, now that we know how to schedule something what can we do? Well, anything you want! Really just imagine the lines in your crontab as if that user was sitting at the command line typing it in. You can run single commands, or scripts. Here is an example of a one-liner.

If you support designers using Adobe Illustrator 10 then you have run into Adobe font cache issues. Wouldn't it be nice if those nasty things just magically disappeared each night?

15 0 * * * find -x / -type f -name 'AdobeFnt*.lst' -exec rm -f {} ;

If you add this to root's crontab then the stupid Adobe font caches vanish every night at 12:15 am.

You can also call scripts from your crontab. I use a simple little script to backup my home folder every hour.
#!/bin/bash

if [ -d /Volumes/TinyDrive/Backup ]
then
/usr/local/bin/psync -d /Users/josh /Volumes/TinyDrive/Backup/josh
exit 0
else
exit 0
fi
I just call the script every hour with my crontab. If the drive is mounted then it backs everything up. If not it just checks again next hour.

All the fun extras...

OK, so what happens after a cron job runs? By default the user who owns the crontab is sent a local e-mail as to the success or errors that resulted. You can alter this behavior.

The easiest way to snuff the results of one command is just to send the output to /dev/null. Looking at my shell script above I send both stdout and stderr to the bitbucket...

@hourly /backup.sh 2>&1 /dev/null

This way it never bugs me with the results. If I were just to send stdout to /dev/null then it would just send me the errors. I can change the output of the crontab as a whole by adding a 'MAILTO=' statement to the beginning of the crontab. If I use a 'MAILTO=""' statement with empty quotes it will disable the mailing feature. (Chalk this up as another BSD family value!)

In addition to the 'MAILTO' variable I can also set the 'LOGNAME', 'SHELL', and 'HOME' variables. Again, check man 5 crontab for more info.

If you want to put line breaks into a command, like a mail command, you can use a '%' to indicate a new line. If you need to actually have a '%' in a command you must escape it.

There is one more, really cool, Apple added feature. Let's say that I have a sync operation that runs every 15 minutes. Now if it is critical data I probably don't want this to run if the power is out and the system is on the UPS. If you prefix a command with '@AppleNotOnBattery' then cron will not execute the command if not on AC power. So...

@AppleNotOnBattery command

is all you need.

How the heck to do any of this...

So, now that we know all about crontabs it's time to make some. The basic command to edit your crontab is very simple

crontab -e

I can also use a -l to list the existing schedules or a -r to remove the user's crontab file.

When it opens the crontab it does so using the default editor which, unless you have changed it, is vim. Now some of you will yell at me for it, but vi is a six headed beast to me and I changed my default editor to pico. Once the file opens up, just create your entries and save them. That's it! Cron will evaluate all the crontabs on the next minute and execute anything that it finds. No HUPing needed.

If I have admin rights I can edit another user's crontab. Let's say I want to add something to root's crontab. I just use the -u flag...

sudo crontab -u root

Now root's crontab will open and you can make the entries you need. If you need to edit another user's crontab then just specify them as the user.

Wrapping up

So that's it! Now that you know how to edit your crontabs just think of all the stuff you can automate. Backups, file archiving, and trash patrol can all be automated. The more you have the system work for you, the less work you need to do for it!

As always, read the man pages and have fun!

Story Options

Advertising

Crontab Basics | 1 comments | Create New Account
The following comments are owned by whomever posted them. This site is not responsible for what they say.
Crontab Basics
Authored by: Anonymous on Tuesday, June 24 2008 @ 09:54 am MDT
A safe place to experiment with crontab commands is Cron Sandbox at HxPI ( www.hxpi.com/cron_sandbox.php ) where you can see straightaway a future schedule of run times for whatever crontab parameters you type in.