Unit

Schedule Periodic Jobs with Anacron

Learn how Anacron runs daily, weekly, and monthly Linux maintenance jobs on systems that may be powered off or asleep.

Anacron is a Linux utility for running periodic jobs when a computer is not guaranteed to remain powered on. Unlike a scheduler that requires an exact clock time, Anacron checks whether a configured number of days has elapsed since a job last ran. If the system was unavailable, the job can run after the system becomes available, subject to its configured delay and execution window.

This lesson assumes basic command-line navigation, shell scripts, file permissions, and service logs. For command-line fundamentals, see Essential Linux Commands. For related time-based scheduling, compare this lesson with cron and systemd timers on your distribution.

What Anacron Does

An Anacron job has a period, measured in days. A period of 1 means the job should run approximately once per day; 7 means approximately once per week; and 30 commonly represents approximately once per month.

Anacron is useful for laptops, workstations, and other systems that may be shut down or asleep. If a daily job would have been due while the machine was off, Anacron can recognize that the job is overdue when the machine starts or when Anacron is otherwise launched. It then waits for the configured delay before starting the job.

Anacron Compared with Cron

Cron is a time-based scheduler. A cron expression can request a command at a particular minute and hour, but the system must be running at that time. If the machine is powered off when the time arrives, a normal cron job is generally missed.

Anacron and cron can coexist. Many Linux distributions use cron-compatible periodic directories such as /etc/cron.daily, /etc/cron.weekly, and /etc/cron.monthly. Anacron may invoke run-parts to execute eligible scripts in those directories. The exact service arrangement differs by distribution, so inspect the installed configuration before adding duplicate entries.

Characteristic — Anacron — cron

Scheduling basis: elapsed days and stored last-run dates — calendar time fields such as minute, hour, day, month, and weekday.

Suitable frequency: daily, weekly, monthly, or less frequent — minute-, hour-, daily-, weekly-, and other calendar schedules.

Behavior while system is off: an overdue periodic job can run after availability — a job at a missed clock time is normally skipped.

Typical use cases: maintenance on laptops and periodic directory processing — precise recurring tasks on continuously running systems.

Execution-time precision: approximate; affected by startup, delays, randomization, and windows — close to the specified time while the scheduler is running.

State tracking: stores a last-run date for each job identifier — does not normally use Anacron-style periodic state records.

Configuration Files and State

The main system configuration file is commonly /etc/anacrontab. It contains environment settings and job entries. A typical installation also uses periodic directories such as /etc/cron.daily, /etc/cron.weekly, and /etc/cron.monthly.

sudo cat /etc/anacrontab

Anacron commonly stores state files in /var/spool/anacron. Each state file records the date on which a job identifier last ran. The path and file naming details can vary, so treat the installed configuration and manual page as authoritative.

sudo ls -l /var/spool/anacron

Distribution-specific packages may place configuration elsewhere or launch Anacron through a service, boot script, timer, or another scheduler. Do not assume that one universal service name exists.

Anacrontab Format

Blank lines and lines beginning with # are ignored. Environment assignments normally appear before job entries. Common settings include:

Setting — Purpose — Example — Operational notes

SHELL: shell used to run commands — SHELL=/bin/sh — use an interpreter available at the specified path.

PATH: command search path — PATH=/sbin:/bin:/usr/sbin:/usr/bin — do not rely on your interactive shell's PATH.

MAILTO: destination for command output mail — MAILTO=root — delivery requires a working local mail system.

RANDOM_DELAY: maximum implementation-defined random addition, in minutes — RANDOM_DELAY=20 — helps spread work after startup.

START_HOURS_RANGE: permitted daily execution window — START_HOURS_RANGE=3-22 — behavior when the window is missed varies by implementation and should be tested.

NO_MAIL_OUTPUT: suppresses output mail where supported — NO_MAIL_OUTPUT=1 — use explicit logs and monitoring if mail is disabled.

A job entry has four main fields:

Field — Purpose — Example value — Key considerations

Period in days: minimum elapsed period before the job is due — 1 — use a value appropriate for the maintenance task.

Delay in minutes: wait after the job is found due — 10 — useful for allowing startup activity to settle.

Job identifier: stable label used for state tracking — local-maintenance — each identifier must be unique and should not be changed casually.

Command: command and arguments to execute — /usr/local/sbin/local-maintenance.sh — prefer absolute paths and predictable arguments.

period-in-days delay-in-minutes job-identifier command

For example, the following entry requests a daily job with a ten-minute startup delay:

1 10 local-maintenance /usr/local/sbin/local-maintenance.sh

Creating a Daily Maintenance Job

Create a root-owned script with an explicit interpreter, absolute paths, controlled output, and safe behavior if it runs more than once.

sudo install -o root -g root -m 0755 /dev/null /usr/local/sbin/local-maintenance.sh
sudo editor /usr/local/sbin/local-maintenance.sh
#!/bin/sh
set -eu

log=/var/log/local-maintenance.log
printf '%s maintenance started\n' "$(date -Is)" >> "$log"

# Use absolute paths for commands when practical.
/usr/bin/find /var/tmp -type f -mtime +14 -print >> "$log"
printf '%s maintenance finished\n' "$(date -Is)" >> "$log"

Add the job to /etc/anacrontab:

SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

1 10 local-maintenance /usr/local/sbin/local-maintenance.sh

Choose a short delay for lightweight work and a longer delay for disk-intensive maintenance. The job should be idempotent: running it again should not create unwanted duplicate effects. Avoid assuming a particular working directory, graphical session, terminal, user home, or interactive input.

Daily, Weekly, and Monthly Directory Jobs

A common arrangement is to run scripts from standard periodic directories through run-parts. The scripts must satisfy the installed run-parts naming rules, normally be executable, and be noninteractive.

1 5 cron.daily run-parts --report /etc/cron.daily
7 15 cron.weekly run-parts --report /etc/cron.weekly
@monthly 25 cron.monthly run-parts --report /etc/cron.monthly

The symbolic form @monthly, the accepted period syntax, and options such as --report depend on the installed Anacron and run-parts implementations. Some systems use a numeric monthly period instead. Check existing configuration and local documentation before copying an example.

Do not add these entries if another installed mechanism already invokes the same directory, or the scripts may run twice. A directory script should have a valid shebang, executable permissions, suitable ownership, compatible naming, absolute paths where practical, and no request for user input.

Delays, Randomization, and Execution Windows

The per-job delay is predictable: a due job waits that many minutes before it starts. RANDOM_DELAY adds a random component, helping prevent many machines or jobs from starting heavy work simultaneously after boot.

RANDOM_DELAY=20

1 10 local-maintenance /usr/local/sbin/local-maintenance.sh
7 30 weekly-maintenance run-parts --report /etc/cron.weekly

In this example, the jobs have different predictable delays, and each may also receive a random delay up to the implementation's interpretation of RANDOM_DELAY. Confirm the behavior with the installed version.

START_HOURS_RANGE=3-22 restricts execution to a daily window from approximately 03:00 through 22:00 according to the implementation. If a system is unavailable during the permitted range, implementations may defer work, skip that day's opportunity, or handle the next launch differently. Verify this behavior on a test system rather than relying on an assumption.

State Tracking and Missed Jobs

When Anacron starts, it compares the current date with the date in each job's state file. If the elapsed period is sufficient, the job is due. Anacron then applies the execution window and delays, runs the command, and records a new date after the run according to the implementation.

The decision is date-based, not a promise of a precise number of hours. A daily job may run soon after startup one day and later after startup another day. It may also be affected by a configured window, random delay, a long-running earlier job, or the way the distribution launches Anacron.

Changing an identifier creates a separate state identity. Removing a state record can also make a job appear never to have run, which may make it immediately due. Changing a period changes the due calculation and can make a job due earlier or later than expected. Back up state information and make changes deliberately.

How Anacron Is Launched

Anacron is normally launched by the operating system rather than kept running as a permanent daemon. Depending on the distribution, activation may come from a service, systemd timer, boot integration, a periodic cron entry, or a package-specific mechanism.

anacron -V
systemctl list-unit-files | grep -i anacron
systemctl list-timers --all | grep -i anacron

On systems without systemd, inspect the package documentation, startup configuration, and existing scheduler entries. Read the installed manual page for supported foreground and test options:

man anacron
anacron --help

Many implementations provide options such as a foreground or debug mode, a force mode, or a syntax-test mode, but names and safety behavior differ. A commonly available syntax check is:

sudo anacron -T

Use a test or foreground mode only after confirming its meaning with anacron --help or man anacron. Force options can run jobs regardless of their normal due state, so use them carefully and never test destructive maintenance against production data without safeguards.

Testing a Job and Confirming Execution

A safe test process is to use a harmless script that writes a timestamp to a dedicated log, validate the configuration, and run the installed implementation's documented foreground or force option. Check the result in several places:

sudo ls -l /usr/local/sbin/local-maintenance.sh
sudo ls -l /var/spool/anacron
journalctl -b | grep -i anacron
sudo tail -n 50 /var/log/local-maintenance.log

When testing due-state behavior, inspect the corresponding state record before and after the run. Do not casually delete the record to “make it run”; deleting it changes Anacron's knowledge of the job and may cause an immediate execution.

Permissions, Security, and Reliability

System Anacron jobs commonly run with elevated privileges. A writable-by-untrusted-users script or configuration file can therefore become a path to privileged command execution. Keep /etc/anacrontab and system scripts owned by root where appropriate, remove unnecessary write permissions, and validate input before using it in commands.

  • Use a clear shebang such as #!/bin/sh or the absolute path to the required interpreter.
  • Define the required PATH and prefer absolute command paths.
  • Use locking or another coordination method when overlapping runs would be harmful.
  • Write useful success and error information to a controlled log.
  • Make maintenance idempotent and safe to retry after an interrupted run.
  • Avoid interactive commands, desktop-dependent commands, and uncontrolled long-running processes.
  • Quote variables in shell scripts and handle temporary files securely.

Validation and Troubleshooting

Symptom — Likely cause — How to verify — Corrective action

Job never runs: Anacron is not installed, not launched, not due, or the entry is invalid — check anacron -V, service or timer listings, syntax, state, and logs — install or enable the correct package mechanism, fix the entry, and wait for or safely test due state.

Job runs at an unexpected time: startup timing, per-job delay, random delay, or execution window — inspect RANDOM_DELAY, START_HOURS_RANGE, logs, and the state date — adjust delays or the window and remember that Anacron is not an exact-time scheduler.

Job runs again after configuration changes: the job identifier changed or its state record was removed — compare identifiers and inspect /var/spool/anacron — restore a stable identifier and avoid deleting state casually.

Script fails silently: missing PATH, wrong interpreter, permissions, working-directory assumptions, or discarded output — run the script with its intended environment and capture standard output and error — use absolute paths, correct permissions, a valid shebang, and explicit logging.

No mail or log output: MAILTO has no working mail delivery, NO_MAIL_OUTPUT suppresses mail, or the script does not log — inspect settings, mail configuration, journal entries, and redirections — configure reliable logging and monitoring rather than depending only on mail.

Jobs do not run after boot: the activation path is absent, failed, or outside the allowed window — inspect service or timer status, boot logs, and START_HOURS_RANGE — repair the launcher, adjust the window, or verify the implementation's missed-window behavior.

Operational Checklist

  1. Confirm that Anacron is installed and identify how the operating system launches it.
  2. Read the existing /etc/anacrontab and check for existing periodic-directory processing.
  3. Give every job a unique, stable identifier.
  4. Use an appropriate period, predictable delay, and optional random delay.
  5. Use absolute paths and a controlled environment.
  6. Set ownership and executable permissions securely.
  7. Validate syntax and test with a harmless, observable command.
  8. Check state files, scheduler logs, script logs, and mail settings after execution.

Summary

Anacron schedules daily-or-less-frequent work by elapsed days and stored state rather than exact clock times. It is especially useful when systems may be powered off or asleep. Configure jobs in the commonly used /etc/anacrontab, choose stable identifiers and safe delays, understand RANDOM_DELAY and START_HOURS_RANGE, and verify how the installed system launches and logs Anacron. Treat privileged jobs as production code: secure them, make them retry-safe, and test their actual behavior.