blog.johanka.net

Scheduling tasks with cron

The Debian packages website defines cron as a process scheduling daemon. However mysterious and arcane it may sound, this is exactly what it is: a background process that runs tasks automatically at regular intervals under the superuser identity or during set times and days as regular user.

If you wonder what these cron.hourly, .daily, .monthly and so on folders in the /etc directory are there for, this is it. When you put a script in one of these folders, it will be executed according to schedule (i.e. once an hour, day, month and so on) under the superuser (root) identity. Assuming your computer is always on, of course.

To automate a task to be performed at set times or on certain days under the regular user identity, you need to create and edit your crontab file. The easiest way to test this if you're just starting out is not to worry about command line text editors at all, and simply employ the echo command, like this:

echo "0 10 * * 1-5 $HOME/weekly.sh" | crontab

The first digit represents minutes, followed by hours, days of month, months and days of week. If unspecified (meaning every) leave an asterisk * sign in place. The | line could easily be replaced with a > sign, since adding a new entry overwrites previous content. If you want to add more entries to the crontab file, just create a text file, edit it with your favourite text editor, and send its content to the crontab using the cat command instead.

crontab -l

will list the content of your crontab file. Sending the content of a blank file to it deletes it.

The example above sets up cron to run my weekly task list script every day at 10 am from Monday to Friday.

If you want to play with scheduling a maintenance task to be run as root, just copy your script to one of the cron folders in the /etc directory. Do not forget to change its permissions to 700 first.

An example script to back up your creative project to a USB drive at regular intervals:

#!/bin/bash

if [ -d /full/path/to/USB ] ; then

cd /full/path/to/USB/
tar -czf reg_backup_$(date +%y%m%d).tar.gz /path/to/your/important/project

else
cd /tmp
tar -czf reg_backup_$(date +%y%m%d).tar.gz /path/to/your/important/project

echo "Hi sweetie, you forgot to plug in the USB drive, so I've put your backup file to tmp. Your $HOSTNAME" > /path/to/Documents/backup-report_$(date +%y%m%d).txt

fi

$HOSTNAME outputs the name of your computer. Please note that you need to enter the full paths ($HOME variable doesn't work if the script is run as root!). You could, of course, specify the paths as your own variables at the beginning of the script:

#!/bin/bash
PROJECTDIR="/path/to/your/project"
BACKUPDIR="/your/backups/folder"

The backup script would then continue like this:

if [ -d $BACKUPDIR ] ; then

cd $BACKUPDIR
tar -czf reg_backup_$(date +%y%m%d).tar.gz $PROJECTDIR

(...)

Since everything run as root produces files that belong to the superuser, it is advisable to add a line to the end of your script that changes the ownership of the backup files back to you:

chown user:group file

The user and group names would commonly be identical.

Play with it and, if you feel like it, tell me how it went.

Next time: setting up your own simplified web server (LAMP). Peppered with insider tips you won't find anywhere else. :-)

copy left Johanka Piskovská, 2020