cron Basics
Backups at 2 AM. Log cleanup every Sunday. Health checks every 5 minutes. Cron runs commands on schedule.
View Current Crontab
Edit Crontab
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
| Schedule | Cron Expression |
|---|---|
| Every minute | * * * * * |
| Every hour | 0 * * * * |
| Every day at midnight | 0 0 * * * |
| Every Sunday at 3 AM | 0 3 * * 0 |
| Every weekday at 9 AM | 0 9 * * 1-5 |
| Every 15 minutes | */15 * * * * |
| First of month at noon | 0 12 1 * * |
Write Your First Cron Job
Add this line:
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:
| String | Equivalent |
|---|---|
@reboot | Run once at startup |
@hourly | 0 * * * * |
@daily | 0 0 * * * |
@weekly | 0 0 * * 0 |
@monthly | 0 0 1 * * |
@yearly | 0 0 1 1 * |
@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:
# 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:
# 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:
# 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:
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:
Or check cron service:
Practical Example
Complete backup cron setup:
# /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
What does '0 */2 * * *' mean?
Quick Reference
| Command | Purpose |
|---|---|
crontab -e | Edit your crontab |
crontab -l | List your cron jobs |
crontab -r | Remove your crontab |
sudo crontab -u user -e | Edit 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,@weeklyshortcuts - Set PATH and environment variables explicitly
- Check
/var/log/syslogfor cron execution logs
Next: managing services with systemd.