Using cronjobs in Linux
En Español  

cron is a daemon that allow us to schedule the launching of programs and scripts. This allow us to automate the execution of diverse tasks in our computer. cron is launched when we boot our computers and stays running in the background.

Every minute cron checks files known as crontabs. A crontab file contains a list of instructions that cron must execute. An instruction consist of a command and either the time at which said command is to be executed, or an expression that cron interprets and, if the current minute matches one of this expressions, cron launches the corresponding command. Every user in a Linux system can have his/her own personal crontab file.

The personal crontab files belonging to individual users are managed with a program called crontab. While every user can have a personal crontab file, not every user may make use of crontab to manipulate it, this depends of how the permissions are set in the system.

Topics
Creating a cron instruction
Cron instruction examples
Using crontab to manage personal crontab files
The global crontab file
Launching a graphical program with cron
Controlling the access to the crontab command
Footnotes

Creating a cron instruction

As previously mentioned, a cron instruction consists of two parts, the execution time, and the command to be executed. Of this instruction only the time needs to be thoroughly explained, the command may be any command that a text shell can interpret.

We can specify the time with either a special string or a time expression. The time expression have the following format, each parameter is separated by a space:

minute hour day_of_the_month month day_of_the_week

The following numeric values are valid for each of the fields:

Minute: Between 0 and 59
Hour: Between 0 and 23
Day of the Month: Between 0 and 31
Month: Between 0 and 12
Day of the Week: Between 0 and 7. Both 0 and 7 equals Sunday.

In addition, in the fields month and day_of_the_week, we can use the first three characters of the names of the months and the names of the days, this is case insensitive. Therefore the valid values for the day of the week are: Mon, Tue, Wed, Thu, Fri, Sat, Sun; and the valid values for the month are: Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec.

We can use a range of numbers, separated by a hyphen, e.g. 10-20 in the hour field represents every hour from 10:00 am to 8:00 pm.

The wild-card * character works as if we specified a range from the first to the last valid number of that particular field; any and all of the possible values are true. If we use the wild-card character in the minutes field, it would execute the cron instruction every minute, if we use it in the hour field, we would run the command hourly, provided the rest of the time matches, e.g. if we specify 10 in the hour, but add a * in the minute field, it would run the instruction every minute between 10:00 am and 10:59 am. If we add a * in the day_of_the_month and a * in the day_of_the_week, this would make the command run every day of the specified month(s).

We can use a list of numbers, separated by commas, e.g. 3,5,7,11 in the months field would represent March, May, July and November.

We can use step values, this are used in conjunction of ranges, as well as with the wild-card * character, and specify numbers to skip. e.g. */2 in the month value would represent 2,4,6,8,10,12. Imagine it as a division, if there is residue, the number is skipped. Therefore in the example any odd minute would we skipped as it would gives us a residue, and the command would be executed in every even minute.

The time at which the tasks are executed depends on the timezone of the computer.

Additionally to this, we can use the following special strings instead of the 5 fields for the time:

@reboot - Run the command when the computer is started
@yearly or @annually - Run it once a year (0 0 1 1 *)
@monthly - Run it once a month (0 0 1 * *)
@weekly - Run it once a week (0 0 * * 0)
@daily or @midnight- Run it once a day (0 0 * * *)
@hourly - Run it once an hour (0 * * * *)

Cron instruction examples

Every Monday at 3:00am:
0 3 * * Mon /usr/bin/command parameters

Every 5 minutes during the month of December:
*/5 * * Dec * /usr/bin/command

At 10:00am, 2:00pm and 6:00pm on July 23:
0 10,14,18 23 Jul * /usr/bin/command

Mondays, Wednesdays and Fridays at 1:15 pm:
15 13 * * 1,3,5 /usr/bin/command

Hourly every Saturday of April:
0 * * Apr Sat /usr/bin/command parameter

Run it every twelve hours, always:
0 */12 * * * /usr/bin/command

The first Wednesday of every month:
0 0 1-7 * Wed /usr/bin/command parameters

Using crontab to manage personal crontab files

Every user in the system may have a personal crontab file, but not every user may make use of crontab to install and edit his crontab file, if the user does not have access to crontab, only the system administrator can create it for him/her. The personal crontab files are stored in /var/spool/cron/crontabs/, however, one should not manually edit this files and should instead allow the command crontab to handle this files.

crontab invokes a text editor of our choosing so we can type our instructions for cron; and checks the integrity of the file and install it once we are done editing it. If we make a mistake, crontab will give us a fairly informative error message and ask us if we want to retry the edition of the file.

Before use crontab we need to set the text editor, we do this by defining the environment variable EDITOR. I am going to set nano as the preferred text editor, as it is a very simple editor to use, but you can use a different one, I personally use vim. If you are working in a graphical environment you can set a graphical text editor such as gedit or kate instead of nano.

export EDITOR=nano

To check the environment variable you can use:

echo $EDITOR

If you want to set this editor as default you need to add this export command to .bashrc so it is executed every time that you open a text shell. To do this you can use:

echo "export EDITOR=nano" >> ~/.bashrc

Ubuntu have a new utility to handle the default text editor, this command is select-editor. select-editor creates a file called .selected_editor in your home folder where it stores the configured value. When we run select-editor we are presented with a screen like this:

Select an editor.  To change later, run 'select-editor'.  1. /bin/ed  2. /bin/nano      <---- easiest  3. /usr/bin/vim.basic  4. /usr/bin/vim.gtk  5. /usr/bin/vim.tinyChoose 1-5 [2]:

In this menu select the second option. If the EDITOR environment variable is set, it overrides the selection from selected-editor.

Once we choose our text editor, we can edit and create the personal crontab file, to do this use the command:

crontab -e

This will open the selected editor. If the file does not exist crontab will create a new file, which may already comes with commentaries. You can add as many instructions as you want for cron to execute.

To check the contents of your personal crontab file at any time you use:

crontab -l

And to delete your personal crontab file you need to use:

crontab -r

Optionally to the use of crontab -e, you can create a file with cron instructions and install this new crontab file, this will replace your current crontab file located in /var/spool/cron/crontabs/ with the contents of you selected file, to do this you need to use:

crontab file_with_cron_instructions.txt

If you have root privileges you can edit, check and delete the crontab of other users by using crontab with the parameter -u followed by the user.

crontab -u juan -e

The global crontab file

There is a global crontab file located in /etc/crontab, this file have the particularities that it doesn't need to be installed with the command crontab, once it is edited the changes are automatically taken into consideration; and that it have an extra field for the user in whose name the command is going to be executed, making the command run with the privileges of said user. This field lies between the time of execution and the command.

You need root privileges to edit this file, to open it in our favorite text editor we can use the following (I use gedit for the example but it may be kate, nano, Vim or other text editor:

sudo gedit /etc/crontab

The following are some examples of instructions in the global crontab file, in this examples I specify the user before the command:

Every Monday at 3:00am:
0 3 * * Mon root /usr/bin/command parameters

Every 5 minutes during the month of December:
*/5 * * Dec * juan /usr/bin/command

Hourly every Saturday of April:
0 * * Apr Sat root /usr/bin/command parameter

Run it every twelve hours, always:
0 */12 * * * juan /usr/bin/command

Launching a graphical program with cron

To do this we just need to set the environment variable DISPLAY before cron launches the program, this is as simple as add:

export DISPLAY=:0 &&

right before the program that we want to launch. The zero represents the first display which is the default display, if you have multiple displays, you may change it to :1 or :2.

For example, I download and mostly seed Linux images with bittorrent, and my preferred bittorrent client is KTorrent. But I only have it running from 10:00 pm to 6:00 am, so I have the following entries in my personal crontab file:

0 22 * * * export DISPLAY=:0 && /usr/bin/ktorrent
0 6 * * * killall ktorrent

Controlling the access to the crontab command

We can control which users have access to the command crontab by making use of the files cron.allow and cron.deny located in the /etc directory. This files are simply a list of users, once per line.

If the file /etc/cron.allow exists, then only the users listed in this file will be able to make use of the crontab command. If this files exists the file /etc/cron.deny is ignored.

But if /etc/cron.allow does not exist, and we have a file /etc/cron.deny, then all the users but the ones listed in /etc/cron.deny will be able to make use of crontab.

And, if neither of this files exist, then it depends of the system configuration whether all users or no user can use crontab. The root user can always make use of crontab. In Debian based systems all users are allowed to use crontabs by default. This is also the case of Slackware.

Footnotes

I use the full path to the program that I launch with cron, but if the program is located in /usr/bin this is not necessary, you can use the name of the program alone.