Skip to main content

How to schedule jobs using the Linux 'cron' utility

Scheduling tasks to run automatically at specific times is essential knowledge for any sysadmin.
Image
Clock with alarm bells

Image by pasja1000 from Pixabay

A skilled sysadmin knows when and how to programmatically schedule tasks to be executed at specific intervals, whether they're recurring or happen a set number of times. You can apply this skill in many scenarios, such as scheduling backups, collecting system logs periodically, or automating basic and repetitive tasks.

[ Keep your most commonly used commands handy with the Linux commands cheat sheet. ]

You can schedule tasks in numerous ways, and in this article, I will focus on the cron utility. My colleague Ken previously wrote a great article about cron, so I recommend you check it out, as well as my previous article about the at command, another way to schedule tasks in Linux.

In this article, I'll try to be as succinct, straightforward, and practical as possible, meaning I won't be able to explore all available options for cron.

How 'cron' works

I'll cover a few basics before playing around with cron. First, cron also uses a daemon (crond) that reads different configuration files. There's a cron file for each user in the /etc/cron.d/ directory, and the /etc/crontab file is system-wide. Every user manages their own scheduled jobs and cron configuration file.

$ sudo systemctl status crond
● crond.service - Command Scheduler
   Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled)
   Active: active (running) since Fri 2022-11-11 15:13:12 -03; 1h 17min ago
 Main PID: 2732 (crond)
    Tasks: 2 (limit: 23644)
   Memory: 73.7M
   CGroup: /system.slice/crond.service
           ├─2732 /usr/sbin/crond -n
           └─4752 /usr/sbin/anacron -s

nov 11 15:13:12 demo.example.local systemd[1]: Started Command Scheduler.
nov 11 15:13:12 demo.example.local crond[2732]: (CRON) STARTUP (1.5.2)
nov 11 15:13:12 demo.example.local crond[2732]: (CRON) INFO (Syslog will be used instead of sendmail.)
nov 11 15:13:12 demo.example.local crond[2732]: (CRON) INFO (RANDOM_DELAY will be scaled with factor 33% if used.)
nov 11 15:13:13 demo.example.local crond[2732]: (CRON) INFO (running with inotify support)
nov 11 15:13:13 demo.example.local CROND[2754]: (root) CMD (sleep 60 && /sbin/katello-tracer-upload > /dev/null 2>&1)
nov 11 16:01:01 demo.example.local CROND[4743]: (root) CMD (run-parts /etc/cron.hourly)
nov 11 16:01:01 demo.example.local anacron[4752]: Anacron started on 2022-11-11
nov 11 16:01:01 demo.example.local anacron[4752]: Will run job `cron.daily' in 43 min.
nov 11 16:01:01 demo.example.local anacron[4752]: Jobs will be executed sequentially

$ ls -l /etc/crontab
-rw-r--r--. 1 root root 451 jan  8  2021 /etc/crontab

$ ls -l /etc/cron.d/
total 16
-rw-r--r--. 1 root root 128 set 30  2021 0hourly
-rw-r--r--. 1 root root 450 set 23 18:11 foreman_scap_client_cron
-rw-r--r--. 1 root root 112 fev 10  2022 katello-tracer-upload
-rw-r--r--. 1 root root 108 fev 24  2022 raid-check

Schedule jobs with 'cron'

To manipulate scheduled cron jobs, you can edit the crontab file (for system-wide tasks) or create files inside the user's cron.d directory (for specific tasks) with the necessary parameters inside them. Below are the most common crontab parameters:

  • -l displays the current crontab (jobs from the current user) on standard output.
  • -r removes the current crontab (jobs from the current user).
  • -e edits the current crontab (jobs from the current user) using the editor specified by the VISUAL or EDITOR environment variables. After you exit the editor, the modified crontab is installed automatically.

The most important part of understanding how cron schedules work is knowing the syntax used in the crontab file, as follows (taken from an empty default crontab file):

$ cat /etc/crontab

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed

Additionally, you can:

  • Use x-y for a range: For example, place 1-5 in the Days column for a job to run from Monday to Friday.
  • Use x,y for lists: For example, place 5,10-13,17 in the Minutes column for a job to run at 5, 10, 11, 12, 13, and 17 minutes past the hour.
  • Use */x to indicate an interval of x: For example, place */7 in the Minutes column to run a job every seven minutes.

[ Want to test your sysadmin skills? Take a skills assessment today. ]

Start by checking whether the current user has any scheduled jobs:

$ crontab -l
no crontab for localuser

Try an example

Suppose you have a directory called /home/localuser/source, and you need it to be backed up incrementally close to the end of every day (11 pm) to the directory /home/localuser/destination. And every Saturday, at noon, you need the /home/localuser/destination to be fully backed up to the /home/localuser/full directory.

The following is the directory structure described above:

$ mkdir source destination full

$ for i in 1 2 3; do touch ./source/file$i.txt; done

$ ls -lR
.:
total 0
drwxrwxr-x. 2 localuser localuser   6 nov 11 17:09 destination
drwxrwxr-x. 2 localuser localuser  57 nov 11 17:10 source

./destination:
total 0

./full:
total 0

./source:
total 0
-rw-rw-r--. 1 localuser localuser 0 nov 11 17:10 file1.txt
-rw-rw-r--. 1 localuser localuser 0 nov 11 17:10 file2.txt
-rw-rw-r--. 1 localuser localuser 0 nov 11 17:10 file3.txt

Next, edit the crontab file and add the necessary parameters to accomplish these tasks:

$ crontab -e
no crontab for localuser - using an empty one
crontab: installing new crontab

$ crontab -l
00 23 * * *	localuser	rsync -av /home/localuser/source /home/localuser/destination
00 12 * * 6	localuser	cp -R /home/localuser/destination/* /home/localuser/full/

After the scheduled job runs, this is the outcome (just a simulation):

$ ls -lR

total 0
drwxrwxr-x. 3 localuser localuser  20 nov 11 18:11 destination
drwxrwxr-x. 3 localuser localuser  20 nov 11 18:12 full
drwxrwxr-x. 2 localuser localuser  57 nov 11 17:10 source

./destination:
total 0
drwxrwxr-x. 2 localuser localuser 57 nov 11 17:10 source

./destination/source:
total 0
-rw-rw-r--. 1 localuser localuser 0 nov 11 17:10 file1.txt
-rw-rw-r--. 1 localuser localuser 0 nov 11 17:10 file2.txt
-rw-rw-r--. 1 localuser localuser 0 nov 11 17:10 file3.txt

./full:
total 0
drwxrwxr-x. 2 localuser localuser 57 nov 11 18:12 source

./full/source:
total 0
-rw-rw-r--. 1 localuser localuser 0 nov 11 18:12 file1.txt
-rw-rw-r--. 1 localuser localuser 0 nov 11 18:12 file2.txt
-rw-rw-r--. 1 localuser localuser 0 nov 11 18:12 file3.txt

./source:
total 0
-rw-rw-r--. 1 localuser localuser 0 nov 11 17:10 file1.txt
-rw-rw-r--. 1 localuser localuser 0 nov 11 17:10 file2.txt
-rw-rw-r--. 1 localuser localuser 0 nov 11 17:10 file3.txt

Finally, to remove the scheduled jobs, simply run crontab -r:

$ crontab -l
00 23 * * *	localuser	rsync -av /home/localuser/source /home/localuser/destination
00 12 * * 6	localuser	cp -R /home/localuser/destination/* /home/localuser/full/

$ crontab -r

$ crontab -l
no crontab for localuser

This is a basic example so you can understand how cron works. I hope you can explore the utility more and find all the other possibilities it provides.

Wrap up

Knowing how to schedule tasks and jobs in your systems is very important. Some system tasks are scheduled by default, so you must understand how they work. Also, you need to automate and schedule deferred and recurring jobs to run whenever necessary to accomplish programmable goals. The cron utility will help you with that, and it's a fundamental tool you need to have in your kit of utilities.

I hope this and my related article on the at utility aid you in understanding this topic and add to your general sysadmin knowledge.

Check out these related articles on Enable Sysadmin

Author’s photo

Alexon Oliveira

Alexon has been working as a Senior Technical Account Manager at Red Hat since 2018, working in the Customer Success organization focusing on Infrastructure and Management, Integration and Automation, Cloud Computing, and Storage Solutions. More about me

Red Hat Summit 2022: On Demand

Get the latest on Ansible, Red Hat Enterprise Linux, OpenShift, and more from our virtual event on demand.

Related Content

OUR BEST CONTENT, DELIVERED TO YOUR INBOX

Privacy Statement