Time-Based Scheduling
The cron daemon is Linux's built-in job scheduler. It runs commands automatically at specified times — backups, health checks, log rotation, report generation.
# Check if cron is running
$ systemctl status cron
● cron.service - Regular background program processing daemon
Loaded: loaded (/lib/systemd/system/cron.service; enabled)
Active: active (running) since Thu 2026-04-10 08:00:00 UTC; 3h agoManaging Cron Jobs
Crontab Syntax
The crontab (cron table) defines scheduled tasks.
# Edit the current user's crontab
$ crontab -e
# List the current user's cron jobs
$ crontab -l
# No crontab for admin
# Edit another user's crontab
$ sudo crontab -u alice -e
# Remove all cron jobs for current user
$ crontab -rCrontab Format
┌───────────── minute (0-59)
│ ┌───────────── hour (0-23)
│ │ ┌───────────── day of month (1-31)
│ │ │ ┌───────────── month (1-12)
│ │ │ │ ┌───────────── day of week (0-6, Sunday=0)
│ │ │ │ │
│ │ │ │ │
* * * * * command
Crontab Syntax Examples
# ┌───────────── minute (0-59)
# │ ┌───────────── hour (0-23)
# │ │ ┌───────────── day of month (1-31)
# │ │ │ ┌───────────── month (1-12)
# │ │ │ │ ┌───────────── day of week (0-6, Sunday=0)
# │ │ │ │ │
# │ │ │ │ │
* * * * * /opt/scripts/health-check.sh| Field | Allowed Values |
|---|---|
| minute | 0-59 |
| hour | 0-23 |
| day of month | 1-31 |
| month | 1-12 |
| day of week | 0-6 (Sunday=0) |
Real-World Crontab Examples
# Run every minute
* * * * * /opt/scripts/monitor.sh
# Run every 5 minutes
*/5 * * * * /opt/scripts/health-check.sh
# Run every hour (at minute 0)
0 * * * * /opt/scripts/hourly-report.sh
# Run daily at 2:00 AM (backup time — low traffic)
0 2 * * * /opt/scripts/backup.sh
# Run daily at midnight
0 0 * * * /opt/scripts/daily-cleanup.sh
# Run every Monday at 8:30 AM
30 8 * * 1 /opt/scripts/weekly-report.sh
# Run on the 1st of every month at 3:00 AM
0 3 1 * * /opt/scripts/monthly-archive.sh
# Run every 15 minutes during business hours (9 AM - 5 PM)
*/15 9-17 * * 1-5 /opt/scripts/business-hours-task.sh
# Run every 30 minutes every day
*/30 * * * * /opt/scripts/30min-task.shSpecial Keywords
# Instead of the 5-field syntax, you can use these:
@reboot /opt/scripts/startup.sh # Run once at reboot
@yearly /opt/scripts/annual.sh # Run once a year (Jan 1, 00:00)
@monthly /opt/scripts/monthly.sh # Run once a month (1st, 00:00)
@weekly /opt/scripts/weekly.sh # Run once a week (Sunday, 00:00)
@daily /opt/scripts/daily.sh # Run once a day (midnight)
@hourly /opt/scripts/hourly.sh # Run once an hourCron Environment
Cron runs in a minimal environment. Variables like $PATH and $HOME may differ from your interactive shell.
# In crontab, always use absolute paths or set PATH
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# Use absolute paths for commands
0 2 * * * /usr/bin/python3 /opt/scripts/backup.py
# Redirect output to a log file
0 2 * * * /opt/scripts/backup.sh >> /var/log/backup.log 2>&1
# Mail results to a specific address (if mail is configured)
MAILTO=ops@example.com
0 2 * * * /opt/scripts/backup.shSystem Cron Jobs
Beyond user crontabs, the system has its own scheduled jobs in these locations:
# System-wide cron directories (run as root)
$ ls /etc/cron.d/
php8.1-cli ← Package-installed cron jobs
logrotate ← Log rotation schedule
# Timed directories (replace cron for some tasks)
$ ls /etc/cron.daily/
0anacron apt-compat chromium dpkg logrotate man-db
$ ls /etc/cron.hourly/
0anacron php8.1-fpm
# User crontabs are stored here
$ ls /var/spool/cron/crontabs/
alice bobanacron — For Non-Continuously Running Systems
cron doesn't run jobs that were missed while the system was off. anacron handles this for daily/weekly/monthly tasks on laptops and servers that aren't always on.
$ cat /etc/anacrontab
# /etc/anacrontab: configuration file for anacron
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/bin
# period delay job-identifier command
1 5 cron.daily run-parts /etc/cron.daily
7 10 cron.weekly run-parts /etc/cron.weekly
@monthly 15 cron.monthly run-parts /etc/cron.monthlyMonitoring Cron
# Check system logs for cron execution
$ grep CRON /var/log/syslog | tail -20
Apr 10 14:00:01 server CRON[12345]: (admin) CMD (/opt/scripts/health-check.sh)
Apr 10 14:05:01 server CRON[12346]: (admin) CMD (/opt/scripts/monitor.sh)
Apr 10 14:10:01 server CRON[12347]: (root) CMD (test -x /usr/sbin/anacron)
# Cron job output is emailed to the user by default
# Check local mail
$ mail
Mail version 8.1.2 01/15/2023.Quick Reference
| Schedule | Crontab Entry |
|---|---|
| Every minute | * * * * * |
| Every 5 minutes | */5 * * * * |
| Every hour | 0 * * * * |
| Daily at 2 AM | 0 2 * * * |
| Weekly on Monday | 0 8 * * 1 |
| Monthly on 1st | 0 3 1 * * |
| Every 15 min (9-5) | */15 9-17 * * 1-5 |
| Task | Command |
|---|---|
| Edit crontab | crontab -e |
| List crontab | crontab -l |
| Remove crontab | crontab -r |
| Edit user's crontab | sudo crontab -u user -e |
Practice Challenge
- Run
crontab -lto check if you have any existing cron jobs - Add a cron job that runs
echo "Cron ran at $(date)" >> /tmp/cron-test.logevery minute - Watch the log file with
tail -f /tmp/cron-test.logto confirm it runs - Remove the test cron job with
crontab -r - List the contents of
/etc/cron.daily/— what scheduled tasks does your system run? - Check
/var/log/syslogfor CRON entries:grep CRON /var/log/syslog | tail -10