107.2 Automate System Administration Tasks by Scheduling Jobs

Weight: 4

Goal: Use cron or anacron to run jobs at regular intervals, and use at to run jobs at a specific time.


1. Two Kinds of Scheduling

Linux has two distinct scheduling systems. Know the difference:

System Purpose
cron (and anacron) Run jobs repeatedly on a schedule (every hour, every day at 3 a.m., every Monday, etc.).
at (and batch) Run a job once, at a specified future time.

A third tool, systemd timers, is a modern replacement for both. The exam expects awareness of it.


2. cron: How It Works

cron is a daemon (crond or cron) that wakes up every minute, checks all the system’s crontabs, and runs whatever jobs are due. It is the standard way to schedule recurring tasks on Linux.

There are two kinds of crontabs:


3. Crontab Format

User crontab (5 fields + command)

*  *  *  *  *   command-to-run
│  │  │  │  │
│  │  │  │  └── day of week (0–7, where 0 and 7 are Sunday)
│  │  │  └───── month (1–12)
│  │  └──────── day of month (1–31)
│  └─────────── hour (0–23)
└────────────── minute (0–59)

System crontab (/etc/crontab and /etc/cron.d/*)

Same as above plus a user field before the command:

*  *  *  *  *  user  command-to-run

This is the single biggest difference to remember for the exam.

Special characters in time fields

Symbol Meaning Example
* every value * in hour = every hour
, list of values 0,15,30,45 = four times an hour
- range 1-5 in day-of-week = Mon–Fri
/ step */10 in minute = every 10 minutes

Named shortcuts

Instead of five fields, you can write:

Shortcut Meaning
@reboot Once at system startup.
@yearly / @annually Once a year (0 0 1 1 *).
@monthly Once a month (0 0 1 * *).
@weekly Once a week (0 0 * * 0).
@daily / @midnight Once a day (0 0 * * *).
@hourly Once an hour (0 * * * *).

Examples to read carefully

0 3 * * *          /usr/local/bin/backup.sh
# Every day at 03:00.

*/15 * * * *       /usr/bin/check-disk.sh
# Every 15 minutes.

0 9-17 * * 1-5     /usr/local/bin/business.sh
# Every hour from 09:00 to 17:00, Monday through Friday.

30 2 1 * *         /usr/local/bin/monthly.sh
# At 02:30 on the 1st of every month.

0 0 * * 0          /usr/local/bin/weekly.sh
# At midnight every Sunday.

Watch out: if you set both day-of-month and day-of-week, cron runs the job when either matches (it’s an OR, not an AND).


4. Managing User Crontabs with crontab

crontab -l            # list YOUR crontab
crontab -e            # edit YOUR crontab (opens $EDITOR)
crontab -r            # remove YOUR crontab — no confirmation, careful!
crontab -i -r         # remove with confirmation
crontab file.txt      # replace YOUR crontab with the contents of file.txt
crontab -l -u alice   # root: list alice's crontab
crontab -e -u alice   # root: edit alice's crontab

crontab -e is the right way to edit — it does syntax checks and reloads cron when you save.


5. The System Crontab and /etc/cron.*/ Directories

/etc/crontab is the main system crontab. A typical Debian/Ubuntu version looks like this:

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

17 *   * * *   root    cd / && run-parts --report /etc/cron.hourly
25 6   * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6   * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6   1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )

This invokes run-parts, which runs every executable script inside the listed directories:

Directory Runs
/etc/cron.hourly/ Once an hour.
/etc/cron.daily/ Once a day.
/etc/cron.weekly/ Once a week.
/etc/cron.monthly/ Once a month.

If you want a job to run on one of these schedules and you don’t need precise timing, just drop an executable script into the right directory. No crontab entry needed.

/etc/cron.d/

A directory of additional system crontab files. Each file uses the same format as /etc/crontab (with the user field). Packages drop their cron jobs here so they don’t have to modify /etc/crontab.


6. Environment in cron Jobs

cron jobs run with a minimal environment. Common gotchas:

You can override variables at the top of a crontab:

SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MAILTO=admin@example.com

0 3 * * * /usr/local/bin/backup.sh

MAILTO="" disables mail entirely. MAILTO=user sends output to that user.


7. Access Control: cron.allow and cron.deny

You can restrict which users may use crontab:

File Effect
/etc/cron.allow If this file exists, only the users listed here may use cron.
/etc/cron.deny If cron.allow does not exist, users listed here are denied.

Rules:

  1. If cron.allow exists, only it matters; cron.deny is ignored.
  2. If neither exists, behavior depends on the distribution (usually all users may use cron, or only root).
  3. One username per line.

at uses the same model with /etc/at.allow and /etc/at.deny (see section 9).


8. anacron

cron only runs jobs at the time they are scheduled. If the machine is off at that time, the job is skipped. That’s fine for servers, but a problem for laptops and desktops.

anacron solves this. It is designed for systems that are not running 24/7. It checks whether a job has run within its specified period; if not, it runs the job now.

/etc/anacrontab

Format (note: different from cron):

period   delay   job-id           command
1        5       cron.daily       run-parts /etc/cron.daily
7        25      cron.weekly      run-parts /etc/cron.weekly
@monthly 45      cron.monthly     run-parts /etc/cron.monthly
Field Meaning
period How often the job should run, in days. @monthly is a shortcut.
delay Minutes to wait after anacron starts before running the job (so multiple jobs don’t all run at once).
job-id Unique tag, used to record when the job last ran.
command The command to run.

How it works

Coexistence with cron

Most modern distributions use both:

That’s why entries in /etc/crontab often look like: test -x /usr/sbin/anacron || ( cd / && run-parts /etc/cron.daily ) — meaning “only run from cron if anacron isn’t installed.”

anacron itself does not run continuously; it is invoked by cron at boot or daily.


9. at and batch: One-Off Jobs

at schedules a command to run once at a future time.

Submitting a job

$ at 22:00
warning: commands will be executed using /bin/sh
at> /usr/local/bin/backup.sh
at> <Ctrl-D>
job 4 at Mon May 12 22:00:00 2026

You can also feed a script via stdin:

$ at 22:00 < script.sh
$ echo "/usr/local/bin/cleanup.sh" | at now + 5 minutes

Time specifications at understands

at 10:30
at noon
at midnight
at teatime              # 16:00
at 10am tomorrow
at 23:00 next monday
at now + 2 hours
at now + 30 minutes
at 14:00 2026-12-31

Managing at jobs

Command Action
atq (or at -l) List pending jobs.
atrm 4 (or at -d 4) Remove job number 4.
at -c 4 Show the content of job 4.

batch

batch is at’s sibling. It runs the command as soon as system load drops below a threshold (traditionally a load average under 0.8), instead of at a specific time.

$ batch
at> /usr/local/bin/big-job.sh
at> <Ctrl-D>

Access control for at

Same model as cron:

Job spool

at jobs are stored in /var/spool/at/ (or /var/spool/atjobs/). You don’t usually look in there.


10. systemd Timers (Awareness)

The exam expects awareness of systemd timers as a modern alternative to cron.

Key points:

systemctl list-timers              # show all active timers
systemctl status mytask.timer
systemctl enable --now mytask.timer

You don’t need to write timer files for the exam, just know they exist and replace cron.


11. Quick Reference for the Exam

Files and directories:

Commands:


12. Likely Exam Questions (Self-Check)

  1. What are the five time fields of a user crontab, in order? minute, hour, day of month, month, day of week.

  2. What extra field does /etc/crontab have that a user crontab doesn’t? The user field (between time fields and the command).

  3. How do you write “every 15 minutes” in cron? */15 * * * *.

  4. What does @daily mean in a crontab? Same as 0 0 * * * — once a day at midnight.

  5. Where are user crontabs stored, and should you edit them directly? In /var/spool/cron/ (or /var/spool/cron/crontabs/). No — always use crontab -e.

  6. How do you list another user’s crontab as root? crontab -l -u username.

  7. What is the difference between cron and anacron? cron runs jobs at exact times and skips them if the machine is off; anacron runs jobs that were missed once the machine is back on. anacron is for desktops/laptops that aren’t on 24/7.

  8. What are the fields of /etc/anacrontab? period (days), delay (minutes), job-id, command.

  9. You want a one-time command to run tomorrow at 3 a.m. Which tool do you use, and how? at. Example: at 03:00 tomorrow.

  10. What is batch? Like at, but runs the command when the system load drops below a threshold instead of at a specified time.

  11. How do you list pending at jobs and remove one? atq to list, atrm <jobnumber> to remove.

  12. If /etc/cron.allow exists with one user “alice” in it, who can use cron? Only alice (and root). Everyone else is denied. /etc/cron.deny is ignored when cron.allow exists.

  13. A cron job runs but can’t find the python3 command, which works fine in your shell. Why? cron’s PATH is minimal. Either use the full path (/usr/bin/python3) or set PATH= at the top of the crontab.

  14. Where does the output of a cron job go by default? It is emailed to the owning user. Redirect to a file or /dev/null to suppress.

  15. A script must run once every hour without precise scheduling. What is the simplest way? Drop an executable script into /etc/cron.hourly/.