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.