Introduction
Cron is a powerful time-based job scheduler in Linux systems that allows you to automate repetitive tasks. This comprehensive guide covers everything from basic cron syntax to advanced scheduling techniques, helping you master task automation in Linux.
What is Cron?
Cron is a daemon that runs in the background and executes scheduled commands at specified times and dates. It’s essential for system maintenance, backups, log rotation, and any recurring tasks.
Key Components:
- Cron Daemon (crond): The background service that executes jobs
- Crontab: Configuration files containing scheduled jobs
- Cron Jobs: Individual scheduled tasks
Cron Syntax and Format
Cron uses a specific syntax with five time fields:
* * * * * command-to-execute
│ │ │ │ │
│ │ │ │ └─── Day of Week (0-6, Sunday=0)
│ │ │ └───── Month (1-12)
│ │ └─────── Day of Month (1-31)
│ └───────── Hour (0-23)
└─────────── Minute (0-59)
Special Characters:
- * (asterisk): Matches any value
- , (comma): Separates multiple values
- – (hyphen): Defines ranges
- / (slash): Defines step values
- ? (question mark): Same as asterisk (some systems)
Managing Crontab
Basic Crontab Commands
# View current user's crontab
crontab -l
# Edit current user's crontab
crontab -e
# Remove current user's crontab
crontab -r
# View another user's crontab (requires sudo)
sudo crontab -l -u username
# Edit another user's crontab
sudo crontab -e -u username
System-wide Crontabs
# System crontab (includes user field)
sudo nano /etc/crontab
# Directory for system scripts
ls /etc/cron.d/
ls /etc/cron.daily/
ls /etc/cron.hourly/
ls /etc/cron.monthly/
ls /etc/cron.weekly/
Common Cron Job Examples
Basic Time Schedules
# Run every minute
* * * * * /path/to/script.sh
# Run at 2:30 PM daily
30 14 * * * /path/to/backup.sh
# Run at midnight every day
0 0 * * * /path/to/daily-cleanup.sh
# Run every Sunday at 3 AM
0 3 * * 0 /path/to/weekly-report.sh
# Run on the 1st of every month at 6 AM
0 6 1 * * /path/to/monthly-task.sh
Advanced Scheduling
# Run every 15 minutes
*/15 * * * * /path/to/frequent-check.sh
# Run every 2 hours
0 */2 * * * /path/to/bi-hourly-task.sh
# Run Monday to Friday at 9 AM
0 9 * * 1-5 /path/to/workday-task.sh
# Run multiple times per day
0 6,12,18 * * * /path/to/tri-daily-task.sh
# Run every weekday at 8:30 AM and 5:30 PM
30 8,17 * * 1-5 /path/to/worktime-task.sh
Special Keywords
# Run at startup
@reboot /path/to/startup-script.sh
# Run once per year (January 1st, 12:00 AM)
@yearly /path/to/annual-task.sh
@annually /path/to/annual-task.sh
# Run once per month (1st day, 12:00 AM)
@monthly /path/to/monthly-task.sh
# Run once per week (Sunday, 12:00 AM)
@weekly /path/to/weekly-task.sh
# Run once per day (12:00 AM)
@daily /path/to/daily-task.sh
@midnight /path/to/daily-task.sh
# Run once per hour
@hourly /path/to/hourly-task.sh
Practical Cron Job Examples
System Maintenance
# Update package lists daily at 2 AM
0 2 * * * /usr/bin/apt update
# Clean package cache weekly
0 3 * * 0 /usr/bin/apt autoremove -y && /usr/bin/apt autoclean
# Rotate logs daily
0 1 * * * /usr/sbin/logrotate /etc/logrotate.conf
# Check disk space hourly
0 * * * * /bin/df -h | /bin/mail -s "Disk Space Report" admin@example.com
Backup Operations
# Database backup daily at 11 PM
0 23 * * * /usr/bin/mysqldump -u backup -p'password' database_name > /backup/db_$(date +%Y%m%d).sql
# File system backup weekly
0 2 * * 0 /usr/bin/rsync -avz /home/ /backup/home-$(date +%Y%m%d)/
# Compress old logs monthly
0 4 1 * * /usr/bin/find /var/log -name "*.log" -mtime +30 -exec gzip {} ;
Monitoring and Alerts
# Check service status every 5 minutes
*/5 * * * * /bin/systemctl is-active apache2 || /bin/mail -s "Apache Down" admin@example.com
# Monitor CPU usage hourly
0 * * * * /usr/bin/uptime | /bin/mail -s "Server Load" admin@example.com
# Check SSL certificate expiration weekly
0 8 * * 1 /usr/bin/openssl x509 -in /etc/ssl/certs/server.crt -checkend 604800 || echo "SSL expiring soon" | /bin/mail -s "SSL Warning" admin@example.com
Environment Variables in Cron
Setting Variables
# Set environment variables in crontab
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=admin@example.com
# Use variables in cron jobs
0 2 * * * $HOME/scripts/backup.sh
Common Environment Issues
# Full path specification (recommended)
0 3 * * * /usr/bin/python3 /home/user/script.py
# Source environment file
0 4 * * * /bin/bash -c 'source /home/user/.bashrc && /home/user/script.sh'
# Set specific environment
0 5 * * * env PATH="/usr/local/bin:$PATH" /home/user/script.sh
Logging and Debugging
Cron Logs
# View cron logs (Ubuntu/Debian)
sudo tail -f /var/log/cron.log
# View cron logs (CentOS/RHEL)
sudo tail -f /var/log/cron
# View system logs for cron
sudo journalctl -u cron.service
# Enable cron logging (if disabled)
sudo nano /etc/rsyslog.conf
# Uncomment: cron.* /var/log/cron.log
sudo systemctl restart rsyslog
Job Output Handling
# Redirect output to file
0 2 * * * /path/to/script.sh > /var/log/script.log 2>&1
# Append output to file
0 2 * * * /path/to/script.sh >> /var/log/script.log 2>&1
# Email output (if MAILTO is set)
0 2 * * * /path/to/script.sh
# Suppress output
0 2 * * * /path/to/script.sh > /dev/null 2>&1
# Log with timestamp
0 2 * * * echo "$(date): Starting backup" >> /var/log/backup.log && /path/to/backup.sh
Advanced Cron Techniques
Conditional Execution
# Run only if file exists
0 2 * * * [ -f /tmp/run_backup ] && /path/to/backup.sh
# Run only on specific days
0 8 * * * [ $(date +%u) -le 5 ] && /path/to/weekday-task.sh
# Run with file locking
0 */5 * * * /usr/bin/flock -n /tmp/script.lock /path/to/script.sh
Complex Scheduling
# Run every 90 minutes
0 0,1,3,4,6,7,9,10,12,13,15,16,18,19,21,22 * * * /path/to/script.sh
# Run on business days excluding holidays
0 9 * * 1-5 [ $(date +%m%d) != "1225" ] && [ $(date +%m%d) != "0101" ] && /path/to/business-task.sh
# Run during business hours only
0 9-17 * * 1-5 /path/to/business-hours-task.sh
Security Considerations
File Permissions
# Secure crontab permissions
chmod 600 /var/spool/cron/crontabs/*
# Secure script permissions
chmod 755 /path/to/script.sh
chown user:user /path/to/script.sh
Best Practices
- Use absolute paths for all commands and scripts
- Set appropriate file permissions
- Validate input in scripts
- Log script execution and errors
- Use file locking for critical scripts
- Regularly review and audit cron jobs
Troubleshooting Common Issues
Jobs Not Running
# Check cron daemon status
sudo systemctl status cron
# Verify crontab syntax
crontab -l | head -5
# Check user permissions
ls -la /var/spool/cron/crontabs/
# Test script manually
/bin/bash /path/to/script.sh
Environment Problems
# Debug environment in cron
* * * * * env > /tmp/cron-env.txt
# Compare with shell environment
env > /tmp/shell-env.txt
diff /tmp/cron-env.txt /tmp/shell-env.txt
Alternative Job Schedulers
Systemd Timers
# Create service file
sudo nano /etc/systemd/system/my-task.service
[Unit]
Description=My scheduled task
[Service]
ExecStart=/path/to/script.sh
# Create timer file
sudo nano /etc/systemd/system/my-task.timer
[Unit]
Description=Run my-task every hour
[Timer]
OnCalendar=hourly
Persistent=true
[Install]
WantedBy=timers.target
# Enable and start
sudo systemctl enable my-task.timer
sudo systemctl start my-task.timer
at Command for One-time Jobs
# Run job once at specific time
echo "/path/to/script.sh" | at 15:30
# Run job once after delay
echo "/path/to/script.sh" | at now + 1 hour
# List scheduled jobs
atq
# Remove scheduled job
atrm job_number
Monitoring and Management Tools
Cron Management Scripts
#!/bin/bash
# cron-backup.sh - Backup all crontabs
BACKUP_DIR="/backup/crontabs"
DATE=$(date +%Y%m%d)
mkdir -p $BACKUP_DIR
# Backup system crontab
cp /etc/crontab $BACKUP_DIR/system-crontab-$DATE
# Backup user crontabs
for user in $(cut -f1 -d: /etc/passwd); do
if crontab -l -u $user 2>/dev/null; then
crontab -l -u $user > $BACKUP_DIR/$user-crontab-$DATE
fi
done
Best Practices Summary
- Use absolute paths for commands and scripts
- Set MAILTO to receive job output and errors
- Test scripts manually before scheduling
- Include error handling in scripts
- Use file locking for scripts that shouldn’t run concurrently
- Log script execution with timestamps
- Regularly review and clean up old jobs
- Document job purposes with comments
- Use version control for important scripts
- Monitor job execution and failure rates
Conclusion
Cron is an essential tool for Linux system automation. Master its syntax, understand environment considerations, and follow security best practices to effectively automate your system tasks. Regular monitoring and maintenance of your cron jobs will ensure reliable task execution and system stability.