Scheduling task with Crontab

If you are a Linux admin, you have come across work that needs to be repeated every so often that you do not like doing and would prefer to automate. Crontab is an awesome tool to do just that, you can setup tasks to run in the background.

What is crontab?

From the crontab manual:

A crontab file contains instructions to the cron(8) daemon of the general form: “run this command at this time on this date”. Each user has their own crontab, and commands in any given crontab will be executed as the user who owns the crontab. Uucp and News will usually have their own crontabs, eliminating the need for explicitly running su(1) as part of a cron command.

Working with crontabs

Before you go any further, you need to ensure you can even setup cron jobs. These two files play an important role:

  • /etc/cron.allow – If this file exists, it must contain your username for you to use cron jobs.
  • /etc/cron.deny – If the cron.allow file does not exist but the /etc/cron.deny file does, then to use cron jobs, you must not be listed in the /etc/cron.deny file.

To see what crontabs are currently running on your system, you can open a terminal and run:

sudo crontab -l

To edit the list of cronjobs you can run:

sudo crontab -e

To remove cronjobs you can run:

sudo crontab -r
NOTE: When editing crontabs, they will be opened in whatever you have set as your default editor.

How to edit crontabs

A crontab entry will look like this:

* * * * * /path/to/your/script.sh

The time and date fields are:

field allowed vallues
minute 0-59
hour 0-23
day of month 0-31
month 0-12
day of week 0-7 (0 or 7 is Sun)

NOTE: The following fields special characters are allowed:

  • Asterisk ( * ) indicates that the cron expression matches for all values of the field. E.g., using an asterisk in the 4th field (month) indicates every month.
  • Slash ( / ) describe increments of ranges. For example 3-59/15 in the 1st field (minutes) indicate the third minute of the hour and every 15 minutes thereafter. The form “*/…” is equivalent to the form “first-last/…”, that is, an increment over the largest possible range of the field.
  • Commas ( , ) are used to separate items of a list. For example, using “MON,WED,FRI” in the 5th field (day of week) means Mondays, Wednesdays and Fridays.
  • Hyphens ( - ) define ranges. For example, 2015-2020 indicates every year between 2015 and 2020 AD, inclusive.

Let’s take a look at this example:

* * * * * /path/to/your/script.sh

We will be running script.sh every minute of every day.

Let’s say you want to run a specific task (script.sh) every weekday at 4:00 AM, you would do the following:

0 4 * * 1-5 /path/to/your/script.sh

Which breaks down as follows:

  • minute: 0
  • hour: 4
  • day: * (every day)
  • month: * (every month)
  • weekday: 1-5 (Monday to Friday)

Doing more

Using KeyWords

Crontab also allows for specific keywords to replace numbers, as in:

keyword what it does numerical equivalent
@reboot Run once, at startup
@yearly Run once a year “0 0 1 1 *”
@annually (same as @yearly)
@monthly Run once a month “0 0 1 * *”
@weekly Run once a week “0 0 * * 0”
@daily Run once a day “0 0 * * *”
@midnight (same as @daily)
@hourly Run once an hour “0 * * * *”

Let’s say you want to run script.sh daily, you would enter the following:

@daily /path/to/your/script.sh

Sending mail

Should you want to get an email of the output of your crontab, you can start your crontab file with the following:

MAILTO="youremail@domain.com"
NOTE: This will cause all output from your cron jobs to be emailed to you as it sets it as default for your file.

Using mailx

Should you want to use mail for single cron jobs, you should install mailx:

aptitude install mailx

This will allow you to set each entry individually:

* * * * * /path/to/your/script.sh 2>&1 | mail -s "Message Subject" youremail@domain.com
NOTE: The 2>&1 in the entry above tells Linux to store standard output (STDOUT) and standard errors (STDERR) as well, creating one datastream for messages & errors.

What if I have issues?

Most of the issues I have seen with crontab is either a wrongly formatted entry or your path is not set properly. Double check your entry and fix anything that is wrong. If it’s a path issue (you can tell because the script works in your shell just fine), you can check your paths by running:

echo $PATH

Which should output something like this:

/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

Once you get your path, open your crontab file again and add this to the start of the file:

PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
NOTE: If you are using the MAILTO option, you will want to enter this under that line.

Read more at crontab.org

Advertisements

Share your thoughts

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s