How to schedule tasks with cron in Linux
How to Schedule Tasks with Cron in Linux
Automation is the cornerstone of efficient system administration, and cron is Linux's most powerful tool for scheduling recurring tasks. Whether you need to backup databases, clean temporary files, or run system maintenance scripts, mastering cron will significantly improve your productivity and system reliability.
This comprehensive guide will take you from cron basics to advanced scheduling techniques, providing practical examples and troubleshooting tips along the way.
What is Cron and Why Use It?
Cron is a time-based job scheduler in Unix-like operating systems, including Linux. It enables users to schedule commands or scripts to run automatically at specified times, dates, or intervals. The name "cron" derives from the Greek word "chronos," meaning time.
Key Benefits of Using Cron
- Automation: Eliminates manual intervention for repetitive tasks
- Reliability: Runs tasks consistently without human oversight
- Efficiency: Schedules resource-intensive tasks during off-peak hours
- System Maintenance: Automates backups, log rotation, and cleanup operations
- Cost-Effective: Reduces administrative overhead and human errors
Understanding the Cron System Architecture
The cron system consists of several components working together:
Cron Daemon (crond)
The cron daemon is a background service that runs continuously, checking for scheduled tasks every minute. It automatically starts at system boot and manages all cron jobs.
Crontab Files
Crontab (cron table) files contain the schedule and commands for cron jobs. There are two types:
- System crontab: Located at `/etc/crontab`
- User crontabs: Individual files for each user
Cron Directories
Linux systems include several directories for different scheduling needs:
- `/etc/cron.hourly/`: Scripts run every hour
- `/etc/cron.daily/`: Scripts run daily
- `/etc/cron.weekly/`: Scripts run weekly
- `/etc/cron.monthly/`: Scripts run monthly
Cron Syntax and Time Format
Understanding cron syntax is crucial for creating effective scheduled tasks. The standard cron format consists of six fields:
```
* command
│ │ │ │ │
│ │ │ │ └─── Day of week (0-7, Sunday = 0 or 7)
│ │ │ └───── Month (1-12)
│ │ └─────── Day of month (1-31)
│ └───────── Hour (0-23)
└─────────── Minute (0-59)
```
Special Characters in Cron
| Character | Description | Example |
|-----------|-------------|---------|
| `` | Matches any value | ` ` (every minute) |
| `,` | Separates multiple values | `1,15 ` (1st and 15th minute) |
| `-` | Defines ranges | `1-5 ` (minutes 1 through 5) |
| `/` | Specifies step values | `/10 *` (every 10 minutes) |
| `@` | Special keywords | `@daily` (once per day) |
Special Keywords
Cron supports several convenient keywords:
- `@yearly` or `@annually`: Run once per year (0 0 1 1 *)
- `@monthly`: Run once per month (0 0 1 )
- `@weekly`: Run once per week (0 0 0)
- `@daily` or `@midnight`: Run once per day (0 0 *)
- `@hourly`: Run once per hour (0 )
- `@reboot`: Run at system startup
Working with Crontab Commands
Viewing Crontab Entries
To display the current user's crontab:
```bash
crontab -l
```
To view another user's crontab (requires appropriate permissions):
```bash
crontab -l -u username
```
Editing Crontab
To edit the current user's crontab:
```bash
crontab -e
```
This opens the default text editor (usually vi or nano) to modify cron jobs.
To edit another user's crontab:
```bash
crontab -e -u username
```
Removing Crontab Entries
To delete all cron jobs for the current user:
```bash
crontab -r
```
Warning: This command removes all entries without confirmation.
Practical Cron Examples and Use Cases
Basic Scheduling Examples
Run a backup script every day at 2:30 AM:
```bash
30 2 * /home/user/scripts/backup.sh
```
Execute a command every 15 minutes:
```bash
/15 * /usr/bin/system-check.py
```
Run a task every Monday at 9:00 AM:
```bash
0 9 1 /opt/weekly-report.sh
```
Execute a command on the first day of every month:
```bash
0 0 1 /home/user/monthly-cleanup.sh
```
Advanced Scheduling Examples
Run a task every weekday at 8:30 AM:
```bash
30 8 1-5 /usr/local/bin/workday-routine.sh
```
Execute multiple times per day:
```bash
0 6,12,18 * /home/user/tri-daily-task.sh
```
Run during specific months:
```bash
0 0 1 6-8 * /home/user/summer-maintenance.sh
```
Complex scheduling with multiple conditions:
```bash
15 14 1 /home/user/scripts/monthly-report.sh
0 /4 /usr/bin/system-monitor.py
45 23 0 /opt/weekly-backup.sh
```
Real-World System Administration Tasks
Automated Database Backup:
```bash
Daily MySQL backup at 3:00 AM
0 3 * mysqldump -u backup_user -p'password' database_name > /backup/db_$(date +\%Y\%m\%d).sql
PostgreSQL backup every 6 hours
0 /6 pg_dump -U postgres mydb > /backup/postgres_backup_$(date +\%Y\%m\%d_\%H).sql
```
Log Management:
```bash
Compress logs older than 7 days
0 2 find /var/log -name ".log" -mtime +7 -exec gzip {} \;
Clean temporary files daily
0 1 * find /tmp -type f -atime +7 -delete
```
System Monitoring:
```bash
Check disk usage every hour
0 df -h | mail -s "Disk Usage Report" admin@company.com
Monitor system load every 5 minutes
/5 * uptime >> /var/log/system-load.log
```
Web Server Maintenance:
```bash
Restart Apache weekly
0 4 0 systemctl restart apache2
Clear cache files
0 0 rm -rf /var/www/html/cache/
SSL certificate renewal check
0 0 1 certbot renew --quiet
```
Environment Variables and Path Considerations
Cron jobs run with a minimal environment, which can cause issues with scripts that depend on specific environment variables or PATH settings.
Setting Environment Variables in Crontab
```bash
Set PATH at the top of crontab
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Set custom variables
HOME=/home/username
MAILTO=admin@example.com
Your cron jobs
0 2 * /home/username/scripts/backup.sh
```
Common Environment Issues and Solutions
Problem: Command not found errors
```bash
Instead of:
0 2 * backup-script.sh
Use full paths:
0 2 * /usr/local/bin/backup-script.sh
```
Problem: Scripts can't find required files
```bash
Set working directory in script or use absolute paths
0 3 * cd /home/user/project && ./run-task.sh
```
Logging and Output Management
Redirecting Output
By default, cron emails output to the user. Control this behavior with redirection:
```bash
Discard all output
0 2 * /path/to/script.sh >/dev/null 2>&1
Log output to file
0 2 * /path/to/script.sh >> /var/log/my-script.log 2>&1
Log errors only
0 2 * /path/to/script.sh 2>> /var/log/errors.log
Send output via email (default behavior)
0 2 * /path/to/script.sh
```
Using MAILTO Variable
Control email notifications:
```bash
Send emails to specific address
MAILTO=admin@company.com
Disable email notifications
MAILTO=""
Multiple recipients
MAILTO="admin1@company.com,admin2@company.com"
```
Monitoring Cron Job Execution
Check cron logs to verify job execution:
```bash
View cron logs on most systems
tail -f /var/log/cron
On Ubuntu/Debian systems
tail -f /var/log/syslog | grep cron
Check specific user's cron activity
grep username /var/log/cron
```
Security Considerations and Best Practices
File Permissions and Security
Secure script permissions:
```bash
Make scripts executable by owner only
chmod 700 /home/user/scripts/backup.sh
Secure sensitive configuration files
chmod 600 /home/user/.backup-config
```
Avoid sensitive data in crontab:
```bash
Bad: Password in crontab
0 2 * mysql -u user -psecret123 -e "SHOW DATABASES;"
Good: Use configuration file
0 2 * mysql --defaults-extra-file=/home/user/.my.cnf -e "SHOW DATABASES;"
```
User Access Control
Restrict cron access using allow/deny files:
```bash
Allow only specific users
echo "username" >> /etc/cron.allow
Deny specific users
echo "restricted_user" >> /etc/cron.deny
```
Best Practices for Cron Jobs
1. Use absolute paths: Always specify full paths for commands and files
2. Test scripts manually: Verify scripts work before scheduling
3. Implement logging: Add proper logging to track execution and errors
4. Handle failures gracefully: Include error handling in scripts
5. Use locking mechanisms: Prevent overlapping executions
6. Regular maintenance: Review and clean up obsolete cron jobs
Example of a robust cron script:
```bash
#!/bin/bash
backup-script.sh with proper error handling
LOCKFILE="/tmp/backup.lock"
LOGFILE="/var/log/backup.log"
Check if another instance is running
if [ -f "$LOCKFILE" ]; then
echo "$(date): Backup already running, exiting" >> "$LOGFILE"
exit 1
fi
Create lock file
touch "$LOCKFILE"
Cleanup function
cleanup() {
rm -f "$LOCKFILE"
}
Set trap to cleanup on exit
trap cleanup EXIT
Your backup logic here
echo "$(date): Starting backup" >> "$LOGFILE"
... backup commands ...
echo "$(date): Backup completed successfully" >> "$LOGFILE"
```
Troubleshooting Common Cron Issues
Cron Job Not Running
Check if cron service is running:
```bash
systemctl status cron
or on older systems
service cron status
```
Verify cron syntax:
```bash
Use online cron validators or test with:
https://crontab.guru/
```
Check system logs:
```bash
grep CRON /var/log/syslog
tail -f /var/log/cron
```
Permission Denied Errors
Verify script permissions:
```bash
ls -la /path/to/script.sh
chmod +x /path/to/script.sh
```
Check directory permissions:
```bash
Ensure user can access all directories in path
ls -la /path/to/
```
Environment-Related Issues
Debug environment in cron:
```bash
Add to crontab to see environment
* env > /tmp/cron-env.txt
```
Compare with user environment:
```bash
env > /tmp/user-env.txt
diff /tmp/user-env.txt /tmp/cron-env.txt
```
Script Execution Issues
Test script in cron-like environment:
```bash
Run script with minimal environment
env -i /bin/sh -c '/path/to/script.sh'
```
Add debugging to scripts:
```bash
#!/bin/bash
set -x # Enable debug output
exec >> /tmp/script-debug.log 2>&1
```
Common Error Messages and Solutions
| Error | Cause | Solution |
|-------|--------|----------|
| "command not found" | Missing PATH | Use absolute paths or set PATH |
| "permission denied" | Script not executable | `chmod +x script.sh` |
| "no such file or directory" | Wrong path | Verify file locations |
| Job runs but no output | Output redirected to /dev/null | Check redirection syntax |
Advanced Cron Techniques
Using Cron with System Directories
Place executable scripts in system directories for easy scheduling:
```bash
Scripts placed here run automatically
/etc/cron.hourly/cleanup-temp
/etc/cron.daily/backup-database
/etc/cron.weekly/system-update
/etc/cron.monthly/log-archive
```
Conditional Cron Jobs
Create smart cron jobs that run based on conditions:
```bash
Only run if file exists
0 2 * [ -f /tmp/run-backup ] && /home/user/backup.sh
Run only on first Monday of month
0 9 1-7 [ "$(date +\%a)" = "Mon" ] && /opt/monthly-report.sh
```
Managing Multiple Server Crons
For managing cron jobs across multiple servers:
```bash
Use configuration management tools
Ansible example:
- cron:
name: "Daily backup"
minute: "0"
hour: "2"
job: "/usr/local/bin/backup.sh"
```
Alternatives to Cron
While cron is excellent for most scheduling needs, consider alternatives for specific use cases:
Systemd Timers
Modern Linux distributions offer systemd timers as an alternative:
```bash
Create timer unit
sudo systemctl edit --force --full backup.timer
```
Anacron
For systems that aren't always running:
```bash
Anacron ensures jobs run even if system was down
1 5 backup.daily /usr/local/bin/backup.sh
```
Conclusion
Mastering cron is essential for effective Linux system administration. This powerful tool enables you to automate routine tasks, improve system reliability, and reduce manual overhead. By understanding cron syntax, following best practices, and implementing proper error handling, you can create robust automated workflows that enhance your system's efficiency.
Remember to:
- Start with simple cron jobs and gradually increase complexity
- Always test scripts manually before scheduling
- Implement proper logging and monitoring
- Follow security best practices
- Regularly review and maintain your cron jobs
With these skills and knowledge, you're well-equipped to harness the full power of cron for your Linux automation needs. Whether you're managing personal servers or enterprise infrastructure, cron will prove invaluable in your system administration toolkit.