Skip to content
Cron Jobs: Scheduling Tasks on Linux

Cron Jobs: Scheduling Tasks on Linux

DodaTech Updated Jun 19, 2026 6 min read

Cron is the Linux job scheduler that runs commands at specified times, dates, or intervals — from nightly backups every day at 2 AM to a health-check script every five minutes.

What You’ll Learn

  • Crontab syntax and the five time fields
  • Common cron schedules with real-world examples
  • Managing crontabs with crontab -e, -l, and -r
  • Logging cron output and debugging failed jobs
  • Systemd timers — the modern alternative to cron

Why Cron Matters

Cron is the simplest way to automate recurring tasks on Linux. Certificate renewal, log rotation, database backups, system updates, monitoring checks — all of these should run automatically, not manually. Cron has been doing this reliably since the 1970s.

DodaZIP uses cron jobs to schedule nightly compression of log archives and weekly database backups.

Learning Path

    flowchart LR
  A[Linux Basics] --> B[Bash Scripting]
  B --> C[Cron Jobs<br/>You are here]
  C --> D[Systemd Timers]
  D --> E[Monitoring & Alerting]
  style C fill:#f90,color:#fff
  

Crontab Syntax

A crontab entry has five time fields followed by the command:

* * * * * command_to_run
│ │ │ │ │
│ │ │ │ └── Day of week (0-7, 0=Sunday)
│ │ │ └──── Month (1-12)
│ │ └────── Day of month (1-31)
│ └──────── Hour (0-23)
└────────── Minute (0-59)

Special Characters

CharacterMeaningExample
*Every* * * * * = every minute
*/nEvery n*/5 * * * * = every 5 minutes
,List0 9,17 * * 1-5 = weekdays at 9 AM and 5 PM
-Range0 9-17 * * * = every hour from 9 AM to 5 PM

Common Schedules

# ┌─ Minute ──┐ ┌─ Hour ──┐ ┌─ Day ──┐ ┌─ Month ──┐ ┌─ Day of Week ──┐
# Every minute
* * * * * /path/to/script.sh

# Every 5 minutes
*/5 * * * * /path/to/script.sh

# Every hour at minute 0
0 * * * * /path/to/script.sh

# Daily at 2:30 AM
30 2 * * * /path/to/script.sh

# Every Monday at 3 AM
0 3 * * 1 /path/to/script.sh

# First day of every month at 1 AM
0 1 1 * * /path/to/script.sh

# Every weekday at 9 AM and 5 PM
0 9,17 * * 1-5 /path/to/script.sh

# Every 15 minutes during business hours
*/15 9-17 * * 1-5 /path/to/script.sh

# Twice a year (June 1 and December 1 at midnight)
0 0 1 6,12 * /path/to/script.sh

Managing Crontabs

# Edit crontab for current user
crontab -e

# List current crontab entries
crontab -l

# Remove entire crontab
crontab -r

# Edit another user's crontab (root only)
sudo crontab -u alice -e

# Restore crontab from file
crontab backup.txt

Complete Example

# /tmp/backup.sh
#!/bin/bash
BACKUP_DIR="/var/backups/database"
TIMESTAMP=$(date +%Y-%m-%d_%H%M)
FILENAME="db_backup_$TIMESTAMP.sql"

mkdir -p "$BACKUP_DIR"
pg_dump myapp > "$BACKUP_DIR/$FILENAME"
gzip "$BACKUP_DIR/$FILENAME"

# Remove backups older than 30 days
find "$BACKUP_DIR" -name "*.sql.gz" -mtime +30 -delete

echo "Backup completed: $FILENAME.gz"
# crontab entry: run daily at 2 AM
0 2 * * * /tmp/backup.sh >> /var/log/backup.log 2>&1

Logging and Output

By default, cron mails output to the user. For practical use, redirect output to a log file:

# Redirect stdout and stderr to a log file
30 2 * * * /path/to/script.sh >> /var/log/myscript.log 2>&1

# Discard output (run silently)
30 2 * * * /path/to/script.sh > /dev/null 2>&1

# Log with timestamp
30 2 * * * echo "[$(date)] Starting backup" >> /var/log/backup.log && \
           /path/to/backup.sh >> /var/log/backup.log 2>&1

Check cron logs:

# View cron execution log (Debian/Ubuntu)
sudo grep CRON /var/log/syslog

# View cron execution log (RHEL/CentOS)
sudo grep CRON /var/log/cron

Expected log output:

Jun 19 02:00:01 server CRON[12345]: (alice) CMD (/tmp/backup.sh >> /var/log/backup.log 2>&1)

Environment Variables in Cron

Cron runs with a minimal environment — PATH is often just /usr/bin:/bin. Always use full paths or set PATH in your crontab:

# Set environment variables at the top of crontab
PATH=/usr/local/bin:/usr/bin:/bin
SHELL=/bin/bash
HOME=/home/alice
MAILTO=alice@example.com

# Now you can use commands without full paths
30 2 * * * backup.sh

Systemd Timers (Modern Alternative)

Cron works, but systemd timers offer better logging, dependency management, and integration with systemd services:

# /etc/systemd/system/backup.service
[Unit]
Description=Database backup service

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
User=postgres
# /etc/systemd/system/backup.timer
[Unit]
Description=Run backup daily at 2 AM

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable backup.timer
sudo systemctl start backup.timer

When to use systemd timers vs cron

  • Cron: Simpler, works everywhere, great for quick jobs
  • Systemd timers: Better logging (journalctl), dependency management, can handle missed runs with Persistent=true

Common Errors

1. Script Works Manually but Not in Cron

Cron runs with a limited PATH. Always use absolute paths or set PATH in crontab. Scripts that rely on environment variables (like $HOME) need explicit definition.

2. Missing Execute Permission

Cron can’t run scripts without execute permission: chmod +x script.sh.

3. No Output Redirect

Without >> logfile 2>&1, cron output is mailed but often lost. Always redirect to a log file.

4. Percent Sign Not Escaped

The % character in crontab must be escaped with backslash. Use $(date +\%Y-\%m-\%d) instead.

5. Time Zone Confusion

Cron uses the system time zone. Check timedatectl if your jobs run at unexpected times.

6. Overlapping Jobs

If a job takes longer than its interval (e.g., backup takes 10 minutes, runs every 5 minutes), jobs overlap. Use flock to prevent:

*/5 * * * * /usr/bin/flock -n /tmp/myscript.lock /path/to/script.sh

Practice Questions

  1. What does */15 * * * * mean? Run every 15 minutes.

  2. How do you set environment variables in a crontab? Add them at the top of the crontab file, before job entries: PATH=/usr/bin:/bin.

  3. Why might a script work manually but fail in cron? Cron has a minimal PATH and doesn’t load profile files. Use full paths or set PATH in crontab.

  4. How do you view cron execution logs? Check /var/log/syslog (Debian) or /var/log/cron (RHEL) with grep CRON.

  5. What is an advantage of systemd timers over cron? Better logging with journalctl, dependency management via systemd units, and Persistent=true for missed runs.

Challenge: Set up a cron job that: (1) runs a backup script daily at 2 AM, (2) logs output with timestamps, (3) removes backups older than 7 days, (4) sends an email alert if the backup fails. Then migrate it to a systemd timer.

FAQ

What happens if the system is off during a scheduled cron job?
The job is skipped. Cron doesn’t catch up on missed runs. For catch-up behavior, use systemd timers with Persistent=true.
How do I prevent a cron email for every job?
Redirect output: >/dev/null 2>&1. Or set MAILTO="" in your crontab.
Can I run a cron job every second?
No — cron’s minimum interval is 1 minute. For sub-minute scheduling, use a loop with sleep in a script or systemd timers with OnUnitActiveSec=5s.
How do I debug a cron job that isn’t running?
Check: (1) cron daemon is running (systemctl status cron), (2) script has execute permission, (3) paths are absolute, (4) check syslog for errors.
What is anacron?
Anacron runs jobs that were missed when the system was off. It’s useful for laptops and desktops that aren’t always on.

What’s Next

TutorialWhat You’ll Learn
Systemd Service ManagementModern service and timer management
Linux Administration BasicsFoundational server administration
Bash Scripting GuideWriting scripts that cron can run

Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro. Updated 2026-06-19.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro