Content:
Automating certain tasks can be extremely useful. Creating backups, syncing data between systems, and deploying patches are all prime candidates for automation.
Setting up this automation on a Linux system can be done using cron jobs.
Cron is a daemon which manages tasks, with a wide range of options to control scheduling. Cron is often used for system processes, and sees wide use for task automation throughout the Linux ecosystem.
This guide will explain how to set up and manage cron jobs.
Installing a Cron Demon
In order to run tasks, you first need to ensure you have a cron demon installed. Linux distributions will generally include a cron demon by default, as certain system tasks use it to run on a schedule.
A way of checking if cron is running is to run
pgrep cron
If this command returns a number (which is the process number of the cron daemon), then cron is installed and running.
If cron is not available, you will need to install one.
When using a cron demon, it’s important to consider how you wish to handle missed events. If the system is down when a task should run, a cron demon can either ignore the event, or run it as soon as possible once the system is back online.
Many cron daemons will run missed tasks, however, the original cron implementation will not. A commonly used daemon is called cronie – this daemon does run missed tasks.
Creating a Cron Job
Cron jobs are saved in a table known as the crontab. To add, edit or remove cron jobs, the following command is used:
crontab -l
The -l flag opens the crontab for viewing – to open in for editing, use
crontab -e
This will open the crontab in the default text editor. Depending on the distro you’re using, you might be asked to choose the editor you wish to use when you first open the crontab.
If you want to use an alternative editor, you can append this to the start of the crontab command.
EDITOR=editor_name
For example, to use gedit, the command would be
EDITOR=gedit crontab -e
User Crontabs
By default, each user will have their own crontab file, and the commands in the crontab will run as the owner of the crontab. For example, running
sudo crontab -l
will open the crontab for the root user. It is recommended to work with the crontab of your user, rather than root, unless it is absolutely necessary.
It’s also possible to open the crontab for a different user, using the command
crontab -u {username} -e
Replace {username} with the user whose crontab you want to edit.
When saving your file, crontab will attempt to install the new crontab file.
Crontab Structure
Each entry in a crontab takes up a single line, which is constructed in a specific format.
The first five parameters specify when the command will run, with the command itself on the end.
The table below shows the meaning of each part of a crontab entry.
| minute | hour | day of month | month | day of week | command |
|---|---|---|---|---|---|
| 20 | 15 | * | * | 6 | /bin/echo “hello” > ~/test |
The value in each column should be separated by a space.
20 15 * * 6 /bin/echo "hello" > ~/test
The entry accepts parameters to define the time and day on which to run the command. The example above will add the string “hello” to the file ‘test’ in the users home directory, and will run at 15:20 on every 6th day of the week (Saturday).
It is also possible to define an interval between runs, using */. For example,
/5 * * * * command
will run every 5 minutes.
If you want to test out setting different cron schedules, there’s a great tool available here which tells you the exact meaning of your entry.
Running a Command
Note that the examples below omit the cron scheduling parameters, ensure these are present in your finished cron entry.
In the example above, we were running a very simple command, printing the word ‘hello’ to the file ~/test.
In practice, it is possible to run a wide variety of scripts using cron, provided you use the correct parameters.
One important thing to note is that cron requires full file paths – this includes paths to system executables. Notice how in our previous example, we call /bin/echo, rather than just echo.
It’s possible to use commands such as cd if required, but again, remember to use the full path to the target directory.
Finding an Executable Path
To find out the full path for an executable, you can use the whereis command.
whereis python3
The output on my machine gives
python: /usr/bin/python /usr/share/man/man1/python.1
In this case, the whereis command tells us that our python3 executable is located at /usr/bin/python. To run a python script, we will need to use the full /usr/bin/python path. If the whereis result gives a blank path, the executable you’re looking for doesn’t exist.
Commands will run using the system shell by default – exactly the same as running commands manually in a terminal. It’s therefore easy to test out commands – simply run them in your terminal.
Running Scripts From Files
Generally, you will want to write a script in a separate file, and call this file in crontab. For example, the command
/usr/bin/python ~/backup.py
will run the python script named ~/backup.py.
As above, remember to use the full file path.
Script Logging
Cron does not provide any built in support for logging – it’s entirely down to the script/command being run to deal with this.
A common method of obtaining a log from a cron command is to direct the output to a file. In fact, we’ve already seen that in our previous example.
To put any script output to a file, simply add
> /path/to/file
after your command, with /path/to/file the path of the file you want the output to be saved to.
/usr/bin/python run.py > ~/pylog.txt
This will log any output from our run.py python script
It’s important to note that the user whose crontab you’re using needs to have write access to this file (and directory, if the file doesn’t yet exist).
By default, only output from the standard output stream (stdout) will be saved. This stream includes any normal output from a script, for example, any print statements in a python script.
If you want to log errors in this file, you can append 2>&1 to the end of the command, like so.
usr/bin/python run.py > ~/pylog.txt 2>&1
This is useful during testing, to catch any errors with the command you’re trying to run.
If you have a mail application set up on your system, your cron daemon will generally be set by default to mail the crontab owner with the command output.
Checking The Crontab
Crontab has a built-in function to check the validity of the crontab file syntax. This does, however, require the path to the crontab you want to test.
You’ll generally find that user crontabs are saved in /var/spool/cron/crontabs/{username}, though check your distro if you don’t find them here.
crontab -T /var/spool/cron/crontabs/dave
The command above will test the crontab for the user named ‘dave’.
If crontab reports a syntax error, take a look at the examples above to make sure all parameters are present and valid.
Things to Remember
Hopefully this guide has made it a little easier to create a cron job. I’ll end with a couple of key points to remember – always use full paths for your crontab commands, and direct your output to a file to view the command output.
