Objective

Schedule recurring tasks with cron, one-time jobs with at, and understand the difference between cron and systemd timers.

Tools & Technologies

  • cron
  • crontab
  • at
  • systemd timers
  • anacron

Key Commands

crontab -e
crontab -l
at 3pm tomorrow
systemctl list-timers
run-parts /etc/cron.daily

Architecture Overview

graph TD FIELD[Cron Field Order] --> M[Minute\n0-59] M --> H[Hour\n0-23] H --> D[Day of Month\n1-31] D --> MO[Month\n1-12] MO --> W[Day of Week\n0-7\n0+7=Sunday] W --> CMD[Command] EXAMPLE[0 2 * * 1] --> MEANING[Every Monday\nat 2:00 AM] style FIELD fill:#1a1a2e,stroke:#00d4ff,color:#e0e0e0 style MEANING fill:#1a1a2e,stroke:#00ff88,color:#e0e0e0

Step-by-Step Process

01
crontab Syntax

Five time fields followed by the command. * means every value. Use crontab.guru online to verify expressions.

# m  h  dom  mon  dow  command
0    2   *    *    *    /usr/local/bin/backup.sh
*/5  *   *    *    *    /usr/local/bin/check.sh
0    9   *    *    1-5  /usr/local/bin/report.sh
30   23  *    *    0    /usr/local/bin/weekly.sh

# Edit current user's crontab
crontab -e
# List
crontab -l
# Edit another user's
sudo crontab -u www-data -e
02
cron Environment

cron runs with a minimal PATH — always use absolute paths in cron scripts.

# Capture cron output to a log
0 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

# Set PATH in crontab (at the top)
PATH=/usr/local/bin:/usr/bin:/bin
[email protected]

# Or in the script itself
#!/bin/bash
export PATH=/usr/local/bin:/usr/bin:/bin
03
at — One-Time Jobs

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

# Schedule
echo 'systemctl restart nginx' | at 3am
at 9:30 tomorrow < script.sh
at 'now + 1 hour' << 'EOF'
  backup.sh
EOF

# Manage
atq          # list pending jobs
atrm 3       # remove job #3
04
systemd Timers

systemd timers are more powerful than cron — they log to journald and support calendar expressions.

# Create timer unit: /etc/systemd/system/backup.timer
[Unit]
Description=Daily backup

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target

sudo systemctl enable --now backup.timer
systemctl list-timers

Challenges & Solutions

  • cron MAILTO= (empty) suppresses email when no SMTP is configured
  • Scripts working in shell but failing in cron — usually PATH or env variable issue

Key Takeaways

  • Always redirect cron output to a log file — silent failures are dangerous
  • Persistent=true in systemd timers runs missed jobs after downtime