User Controlled anacron

Author: akeil
Date: 2013-11-23
Version: 1

In Linux, cron-jobs can be used to execute commands or scripts on a regular schedule. Jobs and their execution times or intervals are specified in a crontab and executed by a cron daemon. When the scheduled execution time is reached, crond will run the job.

This works well in a situation where the machine is up most or all of the time. It works not so well on a typical desktop or laptop PC because cron will not "catch up" on jobs that were missed while the computer was not running.

anacron [6] allows to specify that a job is run at a given interval specified in days (or weeks/months). It does not assume that the system is up 24 hours a day and will run jobs as close as possible to the specified time whenever the system is up.

By default anacron runs system-wide and jobs are executed with the root user. Also, only root has write permissions on /etc/anacrontab or on the /etc/cron.xxx directories.

We will make anacron easily available to a non-root user and - more important - run the scheduled jobs without root privileges.

User Specific anacron

The user-specific crontab is used to launch anacron at fixed intervals. Instead of the default anacrontab a user-specific file is used.

Hourly Jobs

anacron does not support running jobs at an hourly interval. But cron can be used directly to do this.

User crontab

Create or edit the your crontab like this:

$ crontab -e

and create two entries:

# run anacron to check daily/monthly/weekly
01 * * * * /usr/sbin/anacron -t /home/user/.anacron/anacrontab -S /home/user/.anacron/spool

# run hourly jobs
01 * * * * nice run-parts /home/user/.anacron/cron.hourly

(Replace "/home/user" with your home directory.)

anacron will now be launched every hour and check for pending jobs.

The two options in the anacron command are:

-S Use this directory as the spool directory. Timestamp files are kept here.
-t Use this anacrontab instead of the system-wide /etc/anacrontab

Of course, this only works if you create the personal anacrontab and the necessary directories.

$ mkdir ~/.anacron
$ mkdir ~/.anacron/cron.{hourly,daily,weekly,monthly}
$ mkdir ~/.anacron/spool
$ nano ~/.anacron/anacrontab

Edit the anacrontab too look like this:

~/.anacron/anacrontab
------------------------------------------------------

SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/home/user/bin
HOME=/home/user
LOGNAME=user

# period  delay  job-id  command
1  5   user.cron.daily    nice run-parts /home/user/.anacron/cron.daily

7  10  user.cron.weekly   nice run-parts /home/user/.anacron/cron.weekly

@monthly  5  user.cron.monthly  nice run-parts /home/user/.anacron/cron.monthly

(Replace "user" with your username, "/home/user" with your home directory.)

Now, put (or symlink) the scripts to be executed daily/weekly/monthly into the respective directories.

Troubleshooting

Make sure a cron daemon is actually running.

Scripts inside the cron.xxx directories must be executable:

$ chmod u+x the-script

and start with the interpreter specified in the first line.

#!/bin/bash
your-command

anacron Configuration

The relevant configuration file for anacron is /etc/anacrontab (check man anacrontab [2] and man anacron [3]).

An anacrontab-entry contains the following parts:

period delay job-id command
period: A number giving the execution interval in days. @monthly can be used as a special value.
delay: A number, lets anacron wait for n minutes before starting the job.
job-id: A string, used to identify the job. The timestamp files for each jobs are named after the job-id
command: Any shell command to be executed.

The anacrontab will typically specify three jobs to be run daily, weekly and monthly. Jobs to be run are kept (as executable files) in these directories:

  • /etc/cron.daily
  • /etc/cron.weekly
  • /etc/cron.monthly

The job's command looks like this:

nice run-parts --report /etc/cron.daily

The nice command is used to control the scheduling priority for the following command (run man nice for details). When used without the -n option, is assigns a niceness of 10 (which is lower than the processes started immediately from a user session).

run-parts runs all executable files in a given directory.