Secret Code

Scheduling Tasks with Cron on Raspberry Pi

Mike Lewis

Issue 17, November 2018

Making software do its thing at the click of a button is easy, but what about tasks that should be automated?

Scheduling tasks provides a reliable and repeatable trigger of tasks for regular activation of just about any piece of software that doesn’t require human input. Most often, it will be to instigate backups of your data, check for updates, take a measurement, or something else.

We’ll look at how to get this automation system setup and running on a Raspberry Pi, which will open the door for a huge array of capabilities you’ll find useful.

Firstly, it’s worth noting that there isn’t just one way to do this. There are, in fact, multiple methods to run a program when your Raspberry Pi starts up such as .bashrc, rc.local, init.d tab, systemd and crontab. One of the easiest ways to achieve this is to use crontab. Crontab can be used to run a program when the Pi boots or to perform a task at a specified interval, For example, backing up a folder every day at midnight.

Cron gets its name from the Greek word for time, Chronos. Cron is available on just about all Unix-like operating systems. Since Linux drives much of the internet, it has become very popular for scheduling tasks on servers too. Cron is also available on Mac OS, since it’s also based on Linux. Since Windows systems do not stem from a Linux base, Cron is not really available or recommended on a Windows platform, however, a few software solutions deliver similar functionality.

Let’s take a look at some of the ways to create tasks with crontab.

Creating a scheduled task

A task can be a terminal command or a script such as a Shell or Python script. We will create a Python script to use for this tutorial.

Please note that we are using Raspbian Stretch on our Pi, and the following commands have been tested to work with this version.

Let’s start by creating a new directory for this project within your home user directory, then navigate to it from the terminal. We can chain these two commands together by using the && operator, which runs the additional command if the preceding one was successful.

mkdir ~/cron_scripts && cd ~/cron_scripts

Note: ~/ is shorthand for the current users home directory. Example /home/pi/. If using the root user then the home directory will be /root

Now we can create a Python script. To create an empty file, type:

touch add_log_entry.py

Next, we will edit the file using the nano editor. This command also creates a file if it doesn’t already exist.

nano add_log_entry.py

Add the following Python code, then save by pressing Ctrl + X then Y, Enter to confirm. Be sure to replace pi with your username.

import logging, sys
  
logging.basicConfig(
  level=logging.INFO,
  filename=’/home/pi/cron_scripts/crontasks.log’,
  format=’%(asctime)s %(message)s’
)
  
message = sys.argv[1]
  
logging.info(message)

This is a simple script that will create a custom log file, and record a timestamp and a message so that we can see if our crontab tasks were successful.

We make use of Python’s built in logging library to make development easier. Since they’ve done the hard work, why reinvent the wheel?

For the message within our log, we will pass it as a string argument when executing this Python script from the terminal. We can then access the message from the sys.argv list within our script. Consider sys.argv as a list of strings containing the arguments passed from the terminal, each argument is separated by a space.

By default, Cron runs all jobs in the root of the home directory of the user who owns the job. Therefore, we must include the full path so Python knows where to store the log file.

It’s also good to know that Cron does come with some built in logging. By default, it's stored in /var/log/syslog but we will use our custom script anyway for demonstration purposes.

With this script in place, let’s first test to see if things are working as expected.

python add_log_entry.py "Script works!"

If this was successful, a newly created log file should exist inside the cron_scripts directory containing our message. Let’s output the contents of this log file to test:

cat crontasks.log

We should now have a working script, so it's now time to configure Cron to schedule running it as a task.

Editing the Cron Table

To add tasks in Cron use the crontab command with the edit (e) attribute (crontab stands for Cron Table).

crontab -e

When you first run crontab you will be asked to select your preferred editor. We recommend nano (2).

A crontab entry consists of two parts. The interval, and the command that should be executed at that interval.

The interval is broken up into 5 components (minute, hour, day of month, month of year, day of week).

A * symbol means use all values.

Examples:

* * * * * At every minute
0 0 * * * Every day at midnight
5 0 * 8 * At 00:05 Every day in August
5 4 * * sun At 04:05 every Sunday
0 12 1 * * At 12:00 on 1st day of every month

Each of the five interval components can also be one of the following expressions:

,value list separator
- range of values
/ step values

Examples:

*/5 * * * * At every 5th minute
0 9-11 * * * Every hour from 9 through 11
0 12 * 3,6,9,12 1 At 12:00 on Monday in March, June, September and December

Add the following line at the bottom of the file (replacing pi with your username) then Ctrl + X to save and Exit.

*/5 * * * * /usr/bin/python /home/pi/cron_scripts/add_log_entry.py "Cron task successful"

This will run the task every 5 minutes.

It’s good practice to use the full path when calling an application from crontab. i.e.: /usr/bin/python. You can find the path of an application by running the following terminal command:

which python

Wait 5 minutes, then check to see if the task ran successfully.

cat crontasks.log

You should see a similar output:

Run script on Reboot

Running a task when your Pi reboots is easy with crontab.

Edit crontab and add the following command on a new line.

@reboot /usr/bin/python /home/pi/cron_scripts/add_log_entry.py "Pi Rebooted" &

By adding & at the end of command we instruct the Pi to run the task in the background while continuing to start up.

Test this out by rebooting your Pi.

CRON FOR WINDOWS?

Cron is a native Unix application (which therefore covers most Linux / Mac OS systems), however, it's not something you'll really find on Windows. Nevertheless, due to its popularity, a number of Cron-style emulator options do exist, though we can't speak to their reliability or usability.

However, the requirement of scheduling certainly isn't one that's lost on Windows users. Microsoft has long had their own option, Task Scheduler (creatively named, we know).

Task Scheduler is native to Windows and has been included since Windows NT 4.0 (which if you're too young to recall, was released in 1996).

It's been through various upgrades over the years and is still included on Windows 10. This guide is not applicable to Task Scheduler for Windows, however, the user interface is fairly friendly and you shouldn't need too much hand-holding to make similar tasks happen in a Windows environment.

WHERE TO FROM HERE?

Now you have the fundamentals of Cron, you can get to work scheduling tasks you’d like to automate. This could be backing up a folder on your RPi to an external hard drive, taking a snapshot from an IP camera at a slow interval, and many other things!

Cron simply executes a script, so if you can script it, Cron can automate it. This makes it able to work with any software you can write for your Pi! So dive in and let the computers do the repetitive tasks for you!

If you have access to a (non critical) linux-based web server, you can play around with Cron on that system too.

The only real caveat to using Cron is when it goes wrong, and you're unaware. It's always good to have your Cron fire off a quick email or other notification saying "it's done", whatever "it" happens to be.

You may simply find yourself deleting the email each morning as you don't really need to keep it, but you'll surely notice when it doesn't arrive at all.