Scheduling Cron Jobs

June 16, 2022
June 16, 2022
Alex Jackson

Introduction

This article will cover creating a cron job in your JetRails environment. A cron job is a bash script or command that runs according to a schedule. These are often used to run antivirus scanners, update data on a website, or automate repetitive tasks like flushing cache at the end of a work day. Any regularly scheduled activity done via the command line or a script should be inserted into the cron, which is done by editing a user’s crontab file.

Regular editors should not be used to edit the crontab file. A program called crontab should be used instead; Crontab verifies your edit and ensures that no syntax errors exist. Run the following command to edit the current user’s crontab file:

$ crontab -e

If a command or script must be run once and only once at a particular time, at should be used instead.

General crontab format

The format of the crontab file consists of lines, with each line having a schedule specified and the job command on the right. Here is an example:

* * * * * /bin/bash /home/user/cronjob_script.sh

In the example above, the command that will be run is /bin/bash /home/user/cronjob_script.sh with the * * * * * schedule. The first five columns represents a unit time, with increasing units from left to right:

* * * * *
│ │ │ │ └─ Day of Week
│ │ │ └─── Month
│ │ └───── Day of Month
│ └─────── Hour
└───────── Minute
FieldAccepted Values
Minute0-59
Hour0-23
Day of Month1-31
Month1-12, as well as 3-letter names (Jan, Feb, etc.)
Day of Week0-6, as well as 3-letter names (Mon, Tue, etc.)

An asterisk means “for every”, so using all asterisks will make a cron job run every minute of every day of every month.

A useful tool for checking the input schedule of a cron job is crontab.guru. Crontab Guru will give a plain English description of when a cronjob will run.

Operators for lists, ranges, and steps

Crontab has a syntax which uses operators to specify lists, ranges, and steps to allow you to program any schedule. Below is a description of the operators and what they do.

ExpressionRuns At
#<sub>a</sub>,#<sub>b</sub>#<sub>a</sub> and #<sub>b</sub>
#<sub>a</sub>/#<sub>b</sub>every #<sub>b</sub> after #<sub>a</sub>
#<sub>a</sub>-#<sub>b</sub>each time unit in the range #<sub>a</sub> to #<sub>b</sub>
#<sub>a</sub>-#<sub>b</sub>/#<sub>c</sub>each #<sub>c</sub> between #<sub>a</sub> and #<sub>b</sub>

Some examples of these operators in action can be seen below:

ScheduleDescription
0,30 4 * * *minutes 0 and 30 in hour 4
10 12-23/2 * * *minute 10 of every two hours after noon (hour 12)
* * 1-7 * *every minute of every day of the first week of every month
* 12-23/2 * * *every minute past every 2nd hour from hour 12 through 23

To enter comments, use # at the beginning of a line. This also allows disabling cron jobs by commenting them out.

Predefined schedule macros

Some cron implementations support replacing the first five fields with special strings that specify a particular schedule. These include the following:

SpecifierRuns
@rebootAfter rebooting
@yearlyOnce per year
@annuallySame as yearly
@monthlyOnce per month
@weeklyOnce per week
@dailyOnce per day
@midnightSame as daily
@hourlyOnce per hour

Here is an example of a job that runs annually:

@annually /usr/local/bin/script.sh

Environmental variables

On Debian-based systems such as Ubuntu, the crontab supports declaring environmental variables above a job’s line:

SHELL="/bin/bash"
* * * * * /usr/local/bin/run_every_minute.sh

On Red-Hat based systems, cron does not support putting environmental variables above a job. Instead, they should be prepended to the line on the job:

* * * * * [email protected] /usr/local/bin/check_for_errors.sh

Default variables

Variable NameDefault Value
MAILTODefaults to the user who owns the cron job
SHELL/bin/sh

Cron emails

Whenever a cron job produces output, cron sends the output via email to the user who owns it. To prevent this, set MAILTO="". To prevent this for some jobs but not all jobs following MAILTO="", redirect the output to /dev/null. Below is an example of redirecting all output to /dev/null to never receive an email from a job:

* * * * * /usr/local/bin/silent_job.sh 2>&1 > /dev/null

Below is an example redirecting only standard output so that errors will be sent in an email:

* * * * * /usr/local/bin/email_on_errors.sh > /dev/null

There is no way to have a multi-line cron job. If multiple lines are necessary, they should be put in a script which is then scheduled in the crontab.

Caveats and other information

The % special character

The special character % is replaced with a newline and effectively becomes the end of the cron job’s command. Everything after the % is then sent to the command as standard input.

Days-of-week versus days-of-month

You may have noticed that days on which jobs have two fields: its number in the month (1-31) and the day of the week. If * is used in only one of the fields, the job runs when specified in the other field. If both don’t use an asterisk, the job runs when either of the fields match.

For example, * 12 1,15 * 0 runs at noon on the 1st and 15th of every month, as well as every Sunday.

Using day or month names

Names of days of the week may be substituted for numbers for readability. Months of the year support this same substitution. The names of both are the first three letters of the day/month (i.e. Jan, Feb, Sun, Mon) and are case-insensitive. Using names and ranges/lists together (i.e. Sun,Wed,Fri or Jan-Mar) are not supported.

For more information, consult the crontab(5) man page.