UNIX and Linux job scheduling with cron

Here is another excerpt from Easy Linux Commands. Though the book is geared toward Linux, most of the information (including this section on cron) applies to UNIX operating systems as well.

The cron Daemon

The cron daemon is the system task that runs scripted jobs on a pre-determined schedule. The crontab command is used to tell the cron daemon what jobs the user wants to run and when to run those jobs.

Each Linux user can have their own crontab file, if allowed by the System Administrator. The administrator controls use of crontab by including users in the cron.deny file to disallow use of crontab.

crontab Options

The crontab command has several options.

Option Purpose
-e edit the current crontab file using the text editor specified by the EDITOR environment variable or the VISUAL environment variable
-l list the current crontab file
-r remove the current crontab file
-u specifies the user’s crontab to be manipulated. This is usually used by root to manipulate the crontab of other users or can be used by you to correctly identify the crontab to be manipulated if you have used the su command to assume another identity.

Options for the crontab command

crontab can also accept a file name and will use the specified file to create the crontab file. Many users prefer to use this option rather than the crontab -e command because it provides a master file from which the crontab is built, thus providing a backup to the crontab. The following example specifies a file called mycron.tab to be used as the input for crontab.

$ crontab mycron.tab

Here’s how you would use the crontab –l command to view the current cron entries for the logged in user.

$ crontab -l

# Run the Weekly file cleanup task at 6:00AM every Monday
# and send any output to a file called cleanup.lst in the
# /tmp directory
00 06 * * 1 /home/terry/cleanup.ksh > /tmp/cleanup.lst

# Run the Weekly Management Report every Monday at 7:00 AM
# and save a copy of the report in my /home directory
00 07 * * 1 /home/terry/weekly_mgmt_rpt.ksh wprd > /home/terry/weekly_mgmt_rpt.lst

Now if we wanted to delete all the entries in the crontab we can use the –r option.

$ crontab -r

The Format of the crontab File

The crontab file consists of a series of entries specifying what shell scripts to run and when to run it. It is also possible to document crontab entries with comments. Lines which have a pound sign (#) as the first non-blank character are considered comments. Blank lines are completely ignored. Comments cannot be specified on the same line as cron command lines. Comments must be kept on their own lines within the crontab.

There are two types of command lines that can be specified in the crontab: environment variable settings and cron commands. The following sections will provide more detail on these two types of crontab entries.

Environment variable settings

Each environment variable line consists of a variable name, an equal sign (=), and a value. Values that contain spaces need to be enclosed within quotes. The following are some examples of environment variable settings:

color = red
title = ‘My Life in a Nutshell’

It is important to remember that variable names are case sensitive and that system variables are usually defined with upper case names, while user defined variables are defined with lower case names.

Note: Environmental variables are supported in the crontab for many Linux distributions but do not work on all platforms.

crontab Command Lines

Each crontab command line is comprised of six positional fields specifying the time, date and shell script or command to be run. The format of the crontab command line is described in Table 10.2 below:

Field Minute Hour Day of Month Month Day of Week Command
Valid values 0-59 0-23 1-31 1-12 0-7 Command path/command

crontab fields and valid values

NOTE: The use of 7 to indicate Sunday is not supported on all platforms. For best compatibility use 0 for Sunday.

Each of these fields can contain a single number, a range of numbers indicated with a hyphen (such as 2-4), a list of specific values separated by commas (like 2,3,4) or a combination of these designations separated by commas (such as 1,3-5). Any of these fields may also contain an asterisk (*) indicating every possible value of this field. This can all get rather confusing so let’s take a look at a few examples.

The next several examples are all part of the same crontab file. We have broken it up in order to explain each entry individually.

# Run the Weekly file cleanup task at 6:00AM every Monday
# and send any output to a file called cleanup.lst in the
# /tmp directory
00 06 * * 1 /home/terry/cleanup.ksh > /tmp/cleanup.lst

This entry will run the script cleanup.ksh at 0 minutes past the hour, 6 am, every day of the month, every month of the year, but only on Mondays. This illustrates that for a crontab to execute all of the conditions specified must be met, so even though we’ve said every day of the month by making the third field a wildcard, the day also has to meet the final condition that the day is a Monday.

# Run the Weekly Management Report every Monday at 7:00 AM
# and save a copy of the report in my /home directory
00 07 * * 1 /home/terry/weekly_mgmt_rpt.ksh wprd > /home/terry/weekly_mgmt_rpt.lst

This entry is very similar but will execute at 7:00am. Since the hour is in 24 hour format (midnight is actually represented as 00) we know the 07 represents 7:00 a.m. This entry again will only be run once a week.

# Weekly Full Backup - run every Sunday at 1:30AM
30 01 * * 0 /home/terry/full_backup.ksh wprd > /tmp/full_backup.lst

Here we have specified this script to be run at 30 minutes past the hour, the first hour of the day, but only on Sundays. Remember that in the day of the week column Sunday can be represented by either 0 or 7.

# Nightly Incremental Backup - run Monday-Saturday at 1:30AM
30 01 * * 1-6 /home/terry/incr_backup.ksh > /tmp/incr_backup.lst

In this crontab entry we see the same indication for hour and minute as the last entry but we have specified a range for the day of the week. The range 1-6 will cause the incr_backup.ksh to be executed at 1:30 every morning from Monday through Saturday.

# Low disk space alert ... run every 15 minutes, sending
# alerts to key individuals via e-mail
00,15,30,45 * * * * /home/terry/free_space.ksh > /tmp/free_space.lst

This entry has minutes separated by a comma indicating that it should be run at each of the indicated times. Since all the other fields are wildcards (*) the entry will be run on the hour (00), 15 minutes past the hour, 30 minutes past the hour and 45 minutes past the hour.

# Lunch Time Notification - run Monday-Friday at Noon -
# sends a message to all users indicating it's lunch time
00 12 * * 1-5 /home/terry/lunch_time.ksh wprd > /tmp/lunch_time.lst

This lunch reminder is set up to run at 12:00 p.m. Monday through Friday only.

The most important thing to remember is that a crontab entry will execute every time all of its conditions are met. To take the last entry as an example, any time it is 00 minutes past the hour of 12 on any day of the month and any month of the year and the day of the week is between Monday and Friday inclusive (1-5) this crontab will be executed.

You will use wildcards in most crontab entries but be careful where you use them. For instance, if we mistakenly placed a * in the minute position of the last crontab example above we would end up running the script for ever minute of the 12:00 hour instead of just once at the beginning of the hour. I don’t think anyone needs that many reminders to go to lunch, do you?

As mentioned above, the day-of-week field accepts either zero or seven as a value for Sunday. Any of the time/date fields can also contain an asterisk (*) indicating the entire range of values. Additionally, month and day-of-week fields can contain name values, consisting of the first three letters of the month, as indicated in the table below. These may not be supported on all platforms so are rarely used.

Field Valid Entries (case insensitive)
Days of the week sun, mon, tue, wed, thu, fri, sat
Months of year jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec

Day of week and Month abbreviations.

Note: The use of these abbreviations is also not supported on all platforms. For best compatibility use numeric indicators for day and month.

When numbers are used, the user can specify a range of values separated by a hyphen or a list of values separated by commas. In other words, specifying 2-5 in the hour field means 2AM, 3AM, 4AM and 5AM, while specifying 2,5 means only 2AM and 5AM.

We’ve talked an awful lot about how to specify the date and time in the crontab but what about the command? Well, most folks will write shell scripts to execute with their crontab entries but you can actually just execute a command from the crontab as well. Either way make sure you put the absolute path to your command in the crontab.

If the command or script you call in your crontab typically sends output to the screen you will probably want to redirect that output to a log file with the >> symbol so you can check it later. Be careful with this as the log files may get rather large over time!

Easy Linux CommandsFor more tips like this check out my book Easy Linux Commands, only $19.95 from Rampant TechPress.

Buy it now!

unix, linux, cron, crontab, system administration, sysadmin, job scheduling

10 thoughts on “UNIX and Linux job scheduling with cron”

  1. %crontab -e 30 18 4-10 1-12 4 myprogram
    This will run on both the 4the-10th days of the month, and Thursday of the week.

    I only need to run it once a month. The FIRST Thursday occurred between 4th – 10th day of the month. How could I do it?

    Thanks in advance.

  2. That looks right Angela. You can use a wildcard for the month since you want it to run all 12, but either yours or the one below should work.

    30 18 4-10 * 4 /path/to/program

    Cron will only run the job when all the conditions are met, so next month it would run Thursday the the 5th because it is within the day range of 4-10 and the day of the week matches 4 (Thursday.)

    Also, crontab -e will get you into the editor, but you cannot give the job information as an argument on the command line like that.

    Hope this helps. Let me know how it works for you.

  3. Angela replied:Thank you for your reply. The request is to run the program once a
    It should be the First Thursday within days 4-10th of the month. I figured
    it out
    how to do it. The second one should have done the trick ( I am testing
    it). Let me
    know if you agree.

    >> 30 18 4-10 * 4 /path/to/program

    < <-- This will run on the 4th-10th days of the month, AND EVERY Thursday of the week. >> 30 18 4-10 1-12 * if [ “`date +\%a`” = “Thu” ]; then /path/to/program;

    <<-- This will run once a month.

  4. Actually this:

    30 18 4-10 * 4

    will run only once a month. Cron will only run a job if all conditions are met, so for this cron to run it has to be 30 minutes past the hour AND the hour of 6 PM (18) AND the day of the month is between 4 and 10 (inclusive) AND it is any month of the year (*) AND it is a Thursday.

    All these conditions are only met once a month. For this month this would execute Thursday the 5th at 6:30 PM but the following Thursday, the 12th, will fail the “day of the month is between 4 and 10” and it will not be executed.

    Your method would also work but the extra if is really unnecessary.

    Hope this helps.

  5. “Cron will only run a job if all conditions are met” – I don’t think that’s quite right. Here’s what the Wikipedia article about Cronatb says:

    Counterintuitively, if both “day of month” (field 3) and “day of week” (field 5) are present on the same line, then the command is executed when either is true.

  6. Christopher,

    It seems like this varies by platform. I just tried the following crontab entry on Linux, Solaris and Mac OS X (which is based on BSD).

    * * 10-31 * 4 date > /home/oracle/cron_output.txt

    Linux does behave the way I expected it to and did not run this job since the date is not currently in the range of 10-31 (I ran this on Thursday April 5.)

    Much to my surprise, the job did run on Mac OS X and Solaris!

    I guess this falls under the “mileage may vary” category but I’m really surprised this is not more standard.

    Thanks for the comment!

  7. This is weird…

    I tried it on a Linux box today, Tuesday, April 10.

    As expected, the following crontab entry does not run, because the day of month is not in the range 11-31 and the day of week is not 3 (Wednesday):

    * * 11-31 * 3 date > /tmp/cron_output.txt

    But the following crontab entries do run, although only one of the day fields matches:

    * * 11-31 * 2 date > /tmp/cron_output.txt
    Runs because day of week matches, although day of month doesn’t.

    * * 10-31 * 3 date > /tmp/cron_output.txt
    Runs because day of month matches, although day of week doesn’t.

    This is consistent with the man page for crontab(5) on that system.

    Kernel version is 2.6.9, and it’s a Redhat distro. I didn’t find a way to display the version of crontab or the GNU tools.

    Seems this is not even standardized on Linux… 🙂

  8. [brettm@myserver ~]$ rpm -qa | grep cron
    [brettm@myserver ~]$

    vixie-cron : The cron daemon itself.

    crontabs : Crontab is the program used to install, uninstall or list the tables used to drive the cron daemon.

    anacron : A cron-like program that can run jobs lost during downtime.

  9. I have to run a script which has to be executed on every month of first sunday. I tried the below command but its not working. Wat command can i use in crontab for my issue

    30 18 1-7 * 0 /path/to/program

  10. I want to schedule a ftp job from linux machine to windows machine after each 30 seconds. How can I achieve this ?

Leave a Reply

Your email address will not be published. Required fields are marked *