Chapter Objective: Schedule recurring and one-time tasks using cron, at, and batch, and understand how systemd timers offer a modern alternative for scheduled work.

Key commands: crontab -e, crontab -l, at, atq, atrm

Ways to Schedule Work

RHEL offers several tools for running commands automatically, depending on whether the task repeats on a schedule or runs just once at a future time.

ToolUse Case
cronRecurring jobs on a fixed schedule (hourly, daily, specific weekdays, etc.)
atA one-time job that runs once at a specified future time
batchA one-time job that runs when system load permits
systemd timersA modern alternative to cron, integrated with systemd logging and dependencies
🔵 Why It Matters Automation is core to system administration — log rotation, backups, certificate renewal, and health checks all depend on something running reliably without a human remembering to trigger it.

cron and crontab

Each user can maintain their own crontab (cron table) — a list of scheduled commands that run as that user.

# Edit your own crontab (opens in your default editor)
crontab -e

# List your current crontab entries
crontab -l

# Remove your entire crontab
crontab -r

# Edit another user's crontab (root only)
sudo crontab -e -u sarah
⚠️ Warning — Don't Edit Crontab Files by Hand Always use crontab -e rather than editing files under /var/spool/cron/ directly — the command handles locking and validation, and cron may not notice or trust a file that was modified outside of it.

Crontab Field Syntax

# minute hour day-of-month month day-of-week command
30 2 * * * /usr/local/bin/backup.sh
FieldRange
Minute0–59
Hour0–23
Day of month1–31
Month1–12
Day of week0–7 (0 and 7 both mean Sunday)
# Every day at 2:30 AM
30 2 * * * /usr/local/bin/backup.sh

# Every 15 minutes
*/15 * * * * /usr/local/bin/healthcheck.sh

# Every weekday (Mon-Fri) at 6:00 PM
0 18 * * 1-5 /usr/local/bin/report.sh

# The first day of every month at midnight
0 0 1 * * /usr/local/bin/monthly-cleanup.sh

# Multiple specific values, comma-separated
0 9,13,17 * * * /usr/local/bin/reminder.sh
✅ Tip — An Asterisk Means "Every" A field left as * matches every possible value for that position. The pattern to remember: the fewer fields you constrain, the more often the job runs.

System-Wide Cron Jobs

Beyond per-user crontabs, RHEL provides directories for system-wide scheduled jobs, useful for administrator-managed automation not tied to a specific user's account.

LocationPurpose
/etc/crontabSystem-wide crontab; includes a username field the per-user version doesn't have
/etc/cron.d/Additional system-wide crontab files, one per package or purpose
/etc/cron.daily/Scripts run once per day (run via anacron/cron depending on setup)
/etc/cron.hourly/, .weekly/, .monthly/Same idea, at different intervals
🔵 Note — anacron Catches Up Missed Runs On systems that aren't always powered on (like laptops or systems that get shut down overnight), anacron ensures a missed daily/weekly/monthly job still runs once the system is back up, instead of silently skipping it entirely.

One-Time Jobs with at and batch

# Schedule a one-time job for a specific time
at 22:00
at> /usr/local/bin/backup.sh
at> Ctrl+D

# Schedule using natural time expressions
at now + 30 minutes
at 5pm tomorrow
at teatime   # 4pm, if you're curious

# List pending at jobs
atq

# Remove a pending job by its job number
atrm 3

# Schedule a job to run whenever system load is low enough
batch
at> /usr/local/bin/heavy-report.sh
at> Ctrl+D
✅ Tip — at Is for "Once," cron Is for "Repeatedly" Reach for at when you need something to happen a single time in the future (like a scheduled maintenance window) rather than on an ongoing recurring schedule.

systemd Timers

A systemd timer unit (.timer) pairs with a matching .service unit to trigger it on a schedule — a modern alternative to cron that integrates with the rest of systemd, including its logging and dependency management.

# List all active timers and when they next fire
systemctl list-timers

# Enable and start a timer (just like any other unit)
sudo systemctl enable --now backup.timer

# Check status, same as any service
systemctl status backup.timer
🔵 Note — Why Consider Timers Over cron Timers log through the systemd journal automatically, can express dependencies on other units, and support more flexible scheduling (like "run 15 minutes after boot" rather than only wall-clock time). cron remains simpler for a quick, familiar recurring job.

Key Terms for Chapter 3

crontab
A user's table of scheduled recurring jobs, edited with crontab -e
cron
The daemon that executes scheduled crontab entries at the specified times
at
Schedules a command to run once at a specified future time
batch
Schedules a command to run once, when system load is low enough
anacron
Ensures periodic jobs still run after being missed, such as on a system that was powered off
systemd timer
A .timer unit that triggers a matching service unit on a schedule

Review Questions

  1. Write a crontab entry that runs /usr/local/bin/sync.sh every day at 3:15 AM.
  2. What's the difference between the per-user crontab and /etc/crontab?
  3. Why should you always use crontab -e instead of editing a crontab file directly?
  4. What is the difference between at and batch?
  5. What problem does anacron solve that plain cron doesn't handle well?
  6. What command lists all pending at jobs, and what command would remove one?
  7. Name one practical advantage systemd timers have over traditional cron jobs.