Blog ENG

Automating tasks in Linux using Cron

Filip Štetić

Not many of us have the time or energy to run scripts for system backup at 2 AM or ping the server to check if it’s up and running. Fortunately, Linux systems offer the Cron service for automating periodic tasks. The name Cron comes from the Greek word chronos[1] which means time. Tasks that are run by Cron are named Cronjobs and they are defined in the crontab table.

Cron files

Files which define tasks for separate users are stored in the /var/spool/cron directory, and tasks that are defined by the system or applications are stored in the /etc/cron.d directory. Besides those two directories there can also be a /etc/anacrontab file which will be explained later.

The command crontab –e is the most used and easiest way of adding Cronjobs. The flag –e means edit. It opens the user’s crontab file using a standard editor (Nano, Vi, Vim, Emacs, …) and it will also restart the service after saving changes so the new task can be immediately registered. Cron files don’t contain any environment, i.e. they don’t have any built-in environment variables, that’s why they are defined inside the crontab file.

The most important variables are SHELL, MAILTO, and PATH.

  • The SHELL variable tells the system which shell to use for command execution. The most used ones are bash, sh, ksh. It’s defined by the full path to the binary, for example /bin/bash.
  • The MAILTO variable contains an e-mail address where Cron sends information about the task. That is the default way of informing the user, and for a different way the output can be redirected to the standard output. In the case of bash one would use “>” for standard output, “2>” for standard error, and “2>&1” after “>” for both output and error.
  • The PATH variable defines the path which Cron uses to look for files when executing the task. For example, if the task is to execute a script called entrypoint.sh, the path to the directory which contains that script must be defined or the full path to the script must be provided.

Command syntax

The syntax for specifying execution times is specific and at first seems complicated, but with a few tries and online tools such as Crontab Guru it’s easy to learn and get used to. Some users like to have a reminder inside their Cron file which can look like this:

* * * * * command
| | | | |_______ day (week) (0-6 where 0 is Sunday or SUN-SUT)
| | | |_________ month (1-12 or JAN-DEC)
| | |__________ day (month) (1-31)
| |____________ hour (0-23)
|_____________ minute (0-59)

Concrete example:

5 4 31 12 * echo Hello Cron! > output.txt

This line defines a task which will print “Hello Cron!” inside the output.txt file on the 31st of December at 4:05 AM.

There are many options for specifying execution time:

An asterisk (*) represents any value.
A comma (,) is used for a list of values, e.g. 0 1,3,5 * * * means every day at 01:00, 03:00, and 05:00.
A dash () defines a range of values, e.g. 0 0 * * 1-5 means every workday at midnight.
A slash (/) is used for step values, e.g. 0 */2 * * 1 means every Monday at every other hour (00, 02, 04, …). A range can also be defined, 8-16/3 means every third hour at times between 8 AM and 4 PM (8 AM, 11 AM, 2 PM)

Cron also has a special @options format for string periods:

  • @hourly – every starting hour (at 00 minutes)
  • @daily – every day at midnight
  • @weekly – every week on Sunday at midnight
  • @monthly – every first day of the month at midnight
  • @yearly – every year on the 1st of January at midnight
  • @reboot – every time the system starts

Scripts

We have mentioned running scripts with Cron. Frequently we need to run bigger tasks that aren’t just one line. In that case we need to define a SHELL or run the command with the shell defined and make the script executable.

On Linux that can be done with the command chmod +x script and in the Cron file we add:

SHELL=/bin/bash
* * * * * script

or

* * * * * /bin/bash script

Our example

An example of how we use Cron on our SOVA project about which you can read more in another blog post.

SHELL=/bin/bash
00 * * * * ~/entrypoint.sh > ~/cronlog 2>&1

Where entrypoint.sh contains two commands:

source utils.SOVA/env/bin/activate    # activate virtual environment
python utils.SOVA/sync_feedback/main.py    # run python script

That Cronjob transfers images from one server to the other every hour.

Anacron

One of the shortcomings of Cron is that, in case of a task failing, it won’t be repeated. For that very reason there exists Anacron. Anacron has the same functionality as Cron, but if the system was down or there was some other reason why a task couldn’t be run, it will repeat it.

Anacron reads tasks from the configuration file /etc/anacrontab. That file contains a list of tasks which specify the period of execution in days, the delay in minutes, the job identifier and the command to execute.

Using Anacron is easy, just add your cron file inside one of the /etc/cron.[hourly|daily|weekly|monthly] directories, depending on the desired interval.

Further reading

More detailed instructions and explanations can be found using the man (manual) command in Linux.

man 8 cron
man 5 crontab
man 8 anacron
man 5 anacrontab


[1] Ancient Greeks had two words for time: chronos and kairos. Chronos refers to quantitative, measurable time, the time we see on clocks. Kairos represents moments of peace and serenity, when we have a feeling like time has stopped, like when laughing with friends or when watching a nice sunset.