Overview

cron is a time-based job scheduler in Unix-like systems. crontab is the per-user configuration file that lists cronjobs with schedules.

Great for running periodic tasks like backups, scripts, or syncs.

Installation and setup

cron should already be installed on Ubuntu systems. Check if it is installed by running:

dpkg -l cron

If not installed, then install by running:

sudo apt install cron

Now, check if cron is running:

systemctl status cron

Note

Windows equivalent of cron is the Task Scheduler. It has much more functionality and comes preinstalled on Windows systems.

Crontab basics

crontab -l              # View current user's crontab
crontab -e              # Edit current user's crontab
crontab -r              # Remove current user's crontab

Run the above commands with sudo to use root user’s crontab.

Crontab format

Each line = one job:

MIN HOUR DOM MON DOW command
FieldAllowed valuesMeaning
MIN0–59Minute
HOUR0–23Hour (24h)
DOM1–31Day of month
MON1–12 or JAN–DECMonth
DOW0–7 or SUN–SATDay of week (0,7 = Sunday)

Use * to mean “every” and */x to mean every x units starting from 0. E.g., */15 meaning every 15 minutes.

Notice

The */x syntax means “every x units starting from 0” within that field’s range. That is, */x starts from 0 unless explicitly stated otherwise regardless of where it ends.

E.g., */13 * * * * runs at:

0, 13, 26, 39, 52

Then it wraps around back to 0 when the hour changes.

Special strings

Instead of full time fields, the followings are also used:

StringMeaning
@rebootRun at startup
@yearly1 Jan 00:00
@monthly1st of month 00:00
@weeklySun 00:00
@dailyEvery day 00:00
@hourlyEvery hour, on the hour

Good to know

Shell scripts can simply be added to etc/cron.daily/etc/cron.hourly/etc/cron.monthly or /etc/cron.weekly directories and the script will be run accordingly.

Example entries

0 2 * * * /home/user/backup.sh
# Run backup.sh daily at 2:00 AM
 
*/10 * * * * /usr/bin/python3 /home/user/script.py
# Run script every 10 minutes
 
10-30/5 * * * * /home/user/task.sh
# Run task every 5 minutes starting from 10 upto 30: 10, 15, 20, 25, 30
 
30 4 * * 1-5 /home/user/weekday_task.sh
# Run on weekdays at 4:30 AM
 
@reboot /home/user/init.sh
# Run once at boot

Output and logging

By default, output (stdout/stderr) is emailed to the user. To suppress:

* * * * * command >/dev/null 2>&1

Or log to a file:

* * * * * /path/script.sh >> /var/log/myscript.log 2>&1

Or use the logger:

* * * * * /path/script.sh 1> >(logger -t myscript -p user.info) 2> >(logger -t myscript -p user.err)

View the logs by running:

journalctl -t myscript -p info

Additionally view crontab logs by running:

grep CRON /var/log/syslog | grep myscript # Simpliest, and most handy
journalctl -u cron.service                # Full logs

Environment notes

Cron has limited environment variables (including $PATH) support. It is recommended to use absolute paths whenever possible. To export environment variables, add this job1:

* * * * * env > /tmp/env.output

Remove once /tmp/env.output is created.

Use script wrapper to better support:

MIN HOUR DOM MON DOW bash $HOME/bin/wrapper_script.sh

Alternatively, define a source profile:

SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

Can be added at top of crontab -e.


References

Footnotes

  1. https://askubuntu.com/a/23438/1755237