Cron is the time-based job scheduler in Unix-like operating systems. It enables you to automate repetitive tasks like backups, log rotation, system updates, and data processing. Mastering cron is an essential skill for every Linux administrator.
Understanding Cron Syntax
A cron expression consists of five fields followed by the command:
# ┌───────────── minute (0-59)
# │ ┌───────────── hour (0-23)
# │ │ ┌───────────── day of month (1-31)
# │ │ │ ┌───────────── month (1-12)
# │ │ │ │ ┌───────────── day of week (0-7, 0 and 7 = Sunday)
# │ │ │ │ │
# * * * * * command_to_execute
Common Scheduling Patterns
# 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 3:00 AM
0 3 * * * /path/to/backup.sh
# Every Monday at 8:00 AM
0 8 * * 1 /path/to/weekly-report.sh
# First day of every month at midnight
0 0 1 * * /path/to/monthly-cleanup.sh
# Every weekday at 6:00 PM
0 18 * * 1-5 /path/to/workday-task.sh
# Every 15 minutes during business hours
*/15 8-17 * * 1-5 /path/to/check-services.sh
Managing Crontab
# Edit current user crontab
crontab -e
# List current crontab entries
crontab -l
# Edit crontab for specific user (as root)
sudo crontab -u www-data -e
# Remove all crontab entries
crontab -r
# List system-wide cron jobs
ls -la /etc/cron.d/
ls -la /etc/cron.daily/
ls -la /etc/cron.weekly/
ls -la /etc/cron.monthly/
Error Handling and Logging
# Redirect output to log file
0 3 * * * /path/to/backup.sh >> /var/log/backup.log 2>&1
# Suppress all output
0 3 * * * /path/to/script.sh > /dev/null 2>&1
# Send errors to email and log successes
MAILTO=admin@example.com
0 3 * * * /path/to/backup.sh >> /var/log/backup.log 2>&1 || echo "Backup failed" | mail -s "Backup Alert" admin@example.com
Best Practices for Production Cron Jobs
#!/bin/bash
# /scripts/safe-cron-task.sh
LOCKFILE="/tmp/my-task.lock"
LOGFILE="/var/log/my-task.log"
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOGFILE"
}
# Prevent overlapping execution
if [ -f "$LOCKFILE" ]; then
log "ERROR: Previous instance still running. Exiting."
exit 1
fi
trap "rm -f $LOCKFILE" EXIT
touch "$LOCKFILE"
log "Starting task..."
# Your actual task here
if /usr/local/bin/process-data; then
log "Task completed successfully"
else
log "ERROR: Task failed with exit code $?"
# Send alert
curl -s -X POST "https://hooks.slack.com/services/..." \
-H "Content-Type: application/json" \
-d '{"text":"Cron job failed on '$(hostname)'"}'
fi
Systemd Timers as an Alternative
# /etc/systemd/system/backup.service
[Unit]
Description=Daily Backup
[Service]
Type=oneshot
ExecStart=/path/to/backup.sh
# /etc/systemd/system/backup.timer
[Unit]
Description=Run backup daily
[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
[Install]
WantedBy=timers.target
# Enable and start
sudo systemctl enable --now backup.timer
sudo systemctl list-timers
Debugging Cron Issues
- Check cron service status:
systemctl status cron - View cron logs:
grep CRON /var/log/syslog - Environment differences: Cron runs with minimal PATH — always use full paths
- Permissions: Ensure scripts are executable:
chmod +x script.sh - Test manually first: Run the exact command from the cron entry in your terminal
Well-configured cron jobs are the backbone of automated system administration. Follow these practices to build reliable, maintainable automated tasks that run smoothly without constant supervision.