cron Basics

Backups at 2 AM. Log cleanup every Sunday. Health checks every 5 minutes. Cron runs commands on schedule.

View Current Crontab

Terminal
$crontab -l
no crontab for john
$
$# View root's crontab
$sudo crontab -l

Edit Crontab

Terminal
$crontab -e
(opens editor)

First time, it asks which editor to use.

Cron Syntax

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

Examples

ScheduleCron Expression
Every minute* * * * *
Every hour0 * * * *
Every day at midnight0 0 * * *
Every Sunday at 3 AM0 3 * * 0
Every weekday at 9 AM0 9 * * 1-5
Every 15 minutes*/15 * * * *
First of month at noon0 12 1 * *

Write Your First Cron Job

Terminal
$crontab -e

Add this line:

hljs bash
0 2 * * * /home/john/backup.sh >> /var/log/backup.log 2>&1

This runs backup.sh at 2:00 AM every day, logging output.

Always Log Output

Cron runs silently. Redirect output to a log file or you'll never know if something failed.

Special Strings

Instead of five stars, use shortcuts:

StringEquivalent
@rebootRun once at startup
@hourly0 * * * *
@daily0 0 * * *
@weekly0 0 * * 0
@monthly0 0 1 * *
@yearly0 0 1 1 *
hljs bash
@daily /home/john/daily-cleanup.sh
@reboot /home/john/start-services.sh

Common Gotchas

PATH Issues

Cron runs with minimal PATH. Commands might not be found:

hljs bash
# Bad - might fail
0 * * * * my-script.sh

# Good - full paths
0 * * * * /home/john/scripts/my-script.sh

# Or set PATH in crontab
PATH=/usr/local/bin:/usr/bin:/bin
0 * * * * my-script.sh

Environment Variables

Cron doesn't load your shell profile:

hljs bash
# This won't work if DB_PASSWORD is in .bashrc
0 * * * * /home/john/backup.sh

# Solution: source your profile or set variables
0 * * * * source /home/john/.env && /home/john/backup.sh

# Or in the crontab itself
DB_PASSWORD=secret
0 * * * * /home/john/backup.sh

Output Emails

By default, cron emails output to the user. Disable or redirect:

hljs bash
# Send to specific email
MAILTO=admin@example.com
0 2 * * * /home/john/backup.sh

# Disable email
MAILTO=""
0 2 * * * /home/john/backup.sh

# Redirect output instead
0 2 * * * /home/john/backup.sh >> /var/log/backup.log 2>&1

System Cron Directories

For system-wide scheduled tasks:

Terminal
$ls /etc/cron.*
/etc/cron.d: custom-task /etc/cron.daily: logrotate apt /etc/cron.hourly: /etc/cron.weekly: fstrim

Drop scripts in these directories:

  • /etc/cron.hourly/ - Run every hour
  • /etc/cron.daily/ - Run daily
  • /etc/cron.weekly/ - Run weekly
  • /etc/cron.monthly/ - Run monthly
  • /etc/cron.d/ - Custom schedules

Debug Cron Jobs

Check if cron ran:

Terminal
$grep CRON /var/log/syslog | tail -5
Jan 14 02:00:01 server CRON[1234]: (john) CMD (/home/john/backup.sh)

Or check cron service:

Terminal
$systemctl status cron
● cron.service - Regular background program processing daemon Active: active (running)

Practical Example

Complete backup cron setup:

hljs bash
# /home/john/crontab
# Backup database every night at 2 AM
0 2 * * * /home/john/scripts/backup-db.sh >> /var/log/db-backup.log 2>&1

# Clean old backups every Sunday at 3 AM
0 3 * * 0 find /backup -type f -mtime +30 -delete >> /var/log/cleanup.log 2>&1

# Health check every 5 minutes
*/5 * * * * /home/john/scripts/health-check.sh || /home/john/scripts/alert.sh

# Rotate logs daily
@daily /usr/sbin/logrotate /etc/logrotate.conf
Knowledge Check

What does '0 */2 * * *' mean?

Quick Reference

CommandPurpose
crontab -eEdit your crontab
crontab -lList your cron jobs
crontab -rRemove your crontab
sudo crontab -u user -eEdit another user's crontab

Key Takeaways

  • Cron syntax: minute hour day month weekday
  • Use full paths in cron commands
  • Always redirect output to log files
  • Use @daily, @weekly shortcuts
  • Set PATH and environment variables explicitly
  • Check /var/log/syslog for cron execution logs

Next: managing services with systemd.