Understanding the Linux Cron and Crontab

The UNIX/Linux systems have a powerful tool for scheduling tasks while the computer is running. The daemon that is responsible for initiating the tasks (called cronjobs) is called cron, while the tool that lets us edit the configuration is the crontab. Once we understand the basics of cron we can easily master editing the cron files.

There are multiple implementations of the service on different systems, but the associated commands we use are the same. Cron is installed by default with the basic system tools and services. It is an important part of our Linux because it is responsible for scheduling system tasks, checks and clean ups. Cron is started automatically at system startup from the /etc/init.d when entering to a multi-user runlevel.

User cron entries

Moreover cron is usable for non-privileged users too to run their own cronjobs. The cron files of ordinary users are stored in the spool area, and the file names are their user names. The spool area for cron files in Debian are in the /var/spool/cron/crontabs folder. These files are loaded into the memory.

We never edit these files directly! When we want to edit our crontab file, we are going to use the crontab command with the -e option. This command will use the default editor. We can change this behavior with the $EDITOR environment variable.

┌──(tmolnar@DebTop)-[~] 
└─$ export EDITOR=vim && crontab -e

Note that this change is not permanent. Use your shell profile file to set this variable permanently.

After running the command we find ourselves in the editor with some comments and explanations of a cron entries. Here we can set the time and the job we want to run. A basic cron entry will look something like this:

5 * * * * echo "hello"

We can list our cron entries with the crontab -l command. It will print the contents of our crontab file to the standard output.

Cron checks the modification times of the crontab files and this way it knows which entries must be updated in the memory. The system checks the entries every minute and runs the due entries.

System-wide cron entries

System-wide cron entries are a bit different from the user cron entries and they are stored under the /etc/crontab. This file looks like this on Debian Linux:

# *  *  *  *  * user-name command to be executed
17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )

Privileged users can directly edit this file with caution.

The anatomy of a cron entry

Let’s analyze the test user cron entry I posted before:

5 * * * * echo "hello"
  • The first five characters are separated by whitespace and they are the date and time part of the entry.
  • The second part is the command that will run in the name of the crontab owner. It can be a command or also a script.
Date & timeCommand
5 * * * *echo “hello”
User cron entry

Let’s break down the five date and time elements!

5minute (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
Date and time breakdown

In a cron entry the asterisk (*) means “any”. The above cronjob will run every hour at 5 minute past the hour. It is not too useful, but it was great for demonstrating a cron entry. It is the way to create a hourly job. There is much more we can use and to learn about cronjobs.

  • The minute is the minutes of an hour. We can use number from 0 to 59 here or the asterisk stating “any”.
  • The hour is a number stating the hour of the day in 24 hours format.
  • The day of the month is a numerical entry from 1 to 31.
  • The month represents the month of the year with numbers or string.
  • The day of the week is a day from the seven days in numbers or string. It starts with 0 that represents Sunday (sun).

Let’s see some examples to understand it better!

We want to run a backup every month on the 3rd day of the month at 10:00 in the morning:

00 10 3 * * backup.sh

Run a cleanup script every week on Sunday evening at 22:00:

00 22 * * 0 cleanup.sh

We can see that with the table above we can easily analyze and understand a cron entry now. In case of system-wide cron entries there is an additional field, the name of the user that will run the script in the cron entry.

10 21 * * * root /usr/share/scripts/www_cleanup.sh
Date & timeUserCommand
10 21 * * *root/usr/share/scripts/www_cleanup.sh
System-wide cron entry

Be very careful with these entries as they can provide a huge attack surface for a possible attacker to do privilege escalation! If the path of the command is writable by ordinary users they can modify the script to gain root privileges with the cron entry.

The time and date part are the same for user and system-wide cron entries.

There are some useful crontab generators online. They can help in the initial steps of creating or understanding cron entries.

If you have a comment or other opinion, visit Tom’s IT Cafe Discord Server and share it!

Leave a comment