Schedule Tasks with Cron
Table of Contents
1. [Introduction](#introduction) 2. [What is Cron](#what-is-cron) 3. [Cron Architecture](#cron-architecture) 4. [Cron Syntax](#cron-syntax) 5. [Crontab Commands](#crontab-commands) 6. [Special Characters](#special-characters) 7. [Predefined Schedules](#predefined-schedules) 8. [Environment Variables](#environment-variables) 9. [Logging and Monitoring](#logging-and-monitoring) 10. [Best Practices](#best-practices) 11. [Common Examples](#common-examples) 12. [Troubleshooting](#troubleshooting) 13. [Security Considerations](#security-considerations) 14. [Advanced Features](#advanced-features)
Introduction
Cron is a time-based job scheduler in Unix-like operating systems that enables users to schedule jobs (commands or scripts) to run periodically at fixed times, dates, or intervals. It is particularly useful for automating system maintenance tasks, backups, log rotation, and other repetitive operations that need to occur without manual intervention.
The name "cron" comes from the Greek word "chronos," meaning time. Cron has been a fundamental part of Unix systems since the 1970s and remains one of the most reliable and widely used task scheduling systems in modern computing environments.
What is Cron
Cron is a daemon process that runs continuously in the background of Unix-like systems, checking every minute to see if there are any scheduled tasks that need to be executed. It reads configuration files called crontabs (cron tables) that contain lists of commands and their scheduling information.
Key Components
- Cron Daemon (crond): The background service that executes scheduled tasks - Crontab Files: Configuration files containing scheduled tasks - Cron Jobs: Individual scheduled tasks defined in crontab files - System Crontab: System-wide cron configuration - User Crontabs: User-specific cron configurations
Cron Architecture
System Architecture
| Component | Description | Location |
|-----------|-------------|----------|
| Cron Daemon | Main scheduling service | /usr/sbin/crond |
| System Crontab | System-wide tasks | /etc/crontab |
| User Crontabs | User-specific tasks | /var/spool/cron/crontabs/ |
| Cron Directories | Time-based script directories | /etc/cron.hourly/, /etc/cron.daily/ |
| Log Files | Execution logs | /var/log/cron |
Process Flow
1. Cron daemon starts at system boot 2. Reads system and user crontab files 3. Checks every minute for scheduled tasks 4. Executes matching tasks in separate processes 5. Logs execution results 6. Continues monitoring for new tasks
Cron Syntax
The cron syntax consists of five time fields followed by the command to execute. Each field represents a different time unit and can contain specific values, ranges, or special characters.
Basic Format
`
* command-to-execute
| | | | |
| | | | +--- Day of week (0-7, Sunday=0 or 7)
| | | +----- Month (1-12)
| | +------- Day of month (1-31)
| +--------- Hour (0-23)
+----------- Minute (0-59)
`
Field Specifications
| Field | Range | Description | Examples | |-------|--------|-------------|----------| | Minute | 0-59 | Minutes past the hour | 0, 15, 30, 45 | | Hour | 0-23 | Hour of the day (24-hour format) | 0 (midnight), 12 (noon), 23 (11 PM) | | Day of Month | 1-31 | Day of the month | 1, 15, 31 | | Month | 1-12 | Month of the year | 1 (Jan), 6 (Jun), 12 (Dec) | | Day of Week | 0-7 | Day of the week | 0 or 7 (Sunday), 1 (Monday), 6 (Saturday) |
Value Types
| Type | Syntax | Description | Example |
|------|--------|-------------|---------|
| Specific Value | number | Exact time match | 30 14 * (2:30 PM daily) |
| Wildcard | | Match any value | (every minute) |
| Range | start-end | Range of values | 1-5 (Monday to Friday) |
| List | val1,val2,val3 | Multiple specific values | 1,15,30 (1st, 15th, 30th) |
| Step | /step | Every nth value | /5 (every 5 units) |
| Range with Step | start-end/step | Step within range | 9-17/2 (9,11,13,15,17) |
Crontab Commands
Primary Commands
| Command | Description | Usage Example |
|---------|-------------|---------------|
| crontab -l | List current user's crontab | crontab -l |
| crontab -e | Edit current user's crontab | crontab -e |
| crontab -r | Remove current user's crontab | crontab -r |
| crontab -u user | Operate on specific user's crontab | crontab -u john -l |
| crontab file | Install crontab from file | crontab mycron.txt |
Command Examples
#### Listing Crontabs
`bash
List current user's crontab
crontab -lList specific user's crontab (requires privileges)
sudo crontab -u username -lList system crontab
cat /etc/crontab`#### Editing Crontabs
`bash
Edit current user's crontab
crontab -eEdit specific user's crontab
sudo crontab -u username -eEdit system crontab
sudo nano /etc/crontab`#### Installing Crontabs
`bash
Install crontab from file
crontab mycrontab.txtInstall for specific user
sudo crontab -u username mycrontab.txt`Special Characters
Character Reference
| Character | Name | Function | Example | Result |
|-----------|------|----------|---------|---------|
| | Asterisk | Match any value | | Every minute |
| , | Comma | List separator | 1,15,30 | Minutes 1, 15, and 30 |
| - | Hyphen | Range indicator | 1-5 | Minutes 1 through 5 |
| / | Slash | Step operator | /5 * | Every 5 minutes |
| ? | Question mark | No specific value | 0 0 ? | Any day of month |
| L | Last | Last occurrence | 0 0 L | Last day of month |
| W | Weekday | Nearest weekday | 0 0 15W | Weekday nearest 15th |
| # | Hash | Nth occurrence | 0 0 1#2 | Second Monday |
Advanced Character Usage
#### Step Values
`bash
Every 5 minutes
/5 * /path/to/script.shEvery 2 hours during business hours
0 9-17/2 * /path/to/business-script.shEvery 3 months
0 0 1 /3 /path/to/quarterly-report.sh`#### Range Combinations
`bash
Monday to Friday, 9 AM to 5 PM, every hour
0 9-17 1-5 /path/to/workday-task.shWeekends only, every 2 hours
0 /2 * 0,6 /path/to/weekend-task.shFirst week of month, weekdays only
0 9 1-7 * 1-5 /path/to/first-week-task.sh`Predefined Schedules
Cron supports several predefined scheduling keywords that simplify common scheduling patterns.
Standard Keywords
| Keyword | Equivalent | Description | Use Case |
|---------|------------|-------------|----------|
| @yearly | 0 0 1 1 * | Once per year | Annual reports, license renewals |
| @annually | 0 0 1 1 * | Once per year (same as @yearly) | Year-end processing |
| @monthly | 0 0 1 | Once per month | Monthly backups, billing |
| @weekly | 0 0 0 | Once per week | Weekly reports, maintenance |
| @daily | 0 0 * | Once per day | Daily backups, log rotation |
| @midnight | 0 0 * | Once per day (same as @daily) | Overnight processing |
| @hourly | 0 | Once per hour | Frequent monitoring, updates |
| @reboot | N/A | At system startup | Initialize services, mount drives |
Usage Examples
`bash
Annual system audit
@yearly /usr/local/bin/annual-audit.shMonthly log cleanup
@monthly /usr/local/bin/cleanup-logs.shWeekly database backup
@weekly /usr/local/bin/db-backup.shDaily file synchronization
@daily rsync -av /home/ /backup/home/Hourly system monitoring
@hourly /usr/local/bin/system-check.shStartup initialization
@reboot /usr/local/bin/startup-tasks.sh`Environment Variables
Cron jobs run in a minimal environment, which can cause issues with scripts that depend on specific environment variables or PATH settings.
Default Environment
| Variable | Default Value | Description |
|----------|---------------|-------------|
| PATH | /usr/bin:/bin | Limited executable search path |
| SHELL | /bin/sh | Default shell for command execution |
| HOME | User's home directory | User's home directory path |
| LOGNAME | Username | Current user's login name |
| USER | Username | Current user's name |
| MAILTO | Username | Email recipient for job output |
Setting Environment Variables
#### In Crontab
`bash
Set environment variables at the top of crontab
PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin SHELL=/bin/bash MAILTO=admin@example.com HOME=/home/userThen define cron jobs
0 2 * /usr/local/bin/backup-script.sh`#### In Scripts
`bash
#!/bin/bash
Set environment in the script itself
export PATH="/usr/local/bin:/usr/bin:/bin" export DATABASE_URL="postgresql://user:pass@localhost/db"Your script logic here
/usr/local/bin/my-application --config /etc/myapp/config.yml`Common Environment Issues
| Problem | Cause | Solution | |---------|--------|----------| | Command not found | Limited PATH | Set full PATH or use absolute paths | | Missing variables | Minimal environment | Export variables in script or crontab | | Wrong shell behavior | Default /bin/sh | Set SHELL variable to preferred shell | | No email notifications | Default MAILTO | Set MAILTO to desired recipient |
Logging and Monitoring
Proper logging and monitoring are essential for maintaining reliable cron jobs and troubleshooting issues.
System Logs
| Log File | Description | Typical Location |
|----------|-------------|------------------|
| Cron Log | Main cron daemon log | /var/log/cron |
| System Log | General system messages | /var/log/syslog |
| Mail Log | Email notifications | /var/log/mail.log |
| Auth Log | Authentication events | /var/log/auth.log |
Log Analysis Commands
`bash
View recent cron activity
tail -f /var/log/cronSearch for specific user's cron jobs
grep "username" /var/log/cronCheck for cron errors
grep -i "error" /var/log/cronMonitor cron job execution
journalctl -u cron -fView cron logs for specific date
grep "Jan 15" /var/log/cron`Custom Logging
`bash
Redirect output to custom log file
0 2 * /path/to/script.sh >> /var/log/my-script.log 2>&1Log with timestamp
0 2 * echo "$(date): Starting backup" >> /var/log/backup.log && /path/to/backup.shSeparate stdout and stderr
0 2 * /path/to/script.sh >> /var/log/script.out 2>> /var/log/script.err`Best Practices
Script Design
1. Use absolute paths for all commands and files 2. Set proper permissions on scripts and directories 3. Handle errors gracefully with proper exit codes 4. Include logging within scripts for debugging 5. Test scripts manually before scheduling
Scheduling Guidelines
| Practice | Reason | Example | |----------|--------|---------| | Avoid overlapping jobs | Prevent resource conflicts | Use locking mechanisms | | Stagger similar jobs | Distribute system load | Offset backup times | | Use appropriate timing | Match business requirements | Run reports after data updates | | Plan for maintenance | Allow for system updates | Schedule around maintenance windows |
Error Handling
`bash
#!/bin/bash
Example script with proper error handling
Set strict error handling
set -euo pipefailDefine log file
LOGFILE="/var/log/my-script.log"Function to log messages
log_message() { echo "$(date '+%Y-%m-%d %H:%M:%S'): $1" >> "$LOGFILE" }Main script logic with error handling
main() { log_message "Starting script execution" if ! command -v required_command &> /dev/null; then log_message "ERROR: required_command not found" exit 1 fi if ! /path/to/critical/operation; then log_message "ERROR: Critical operation failed" exit 1 fi log_message "Script completed successfully" }Execute main function
main "$@"`Common Examples
System Maintenance
`bash
Daily log rotation at 3 AM
0 3 * /usr/sbin/logrotate /etc/logrotate.confWeekly system update check
0 2 0 /usr/bin/apt update && /usr/bin/apt list --upgradableMonthly disk cleanup
0 1 1 /usr/bin/find /tmp -type f -mtime +30 -deleteQuarterly security audit
0 0 1 /3 /usr/local/bin/security-audit.sh`Backup Operations
`bash
Daily database backup at 2 AM
0 2 * /usr/local/bin/mysqldump -u backup -p password database > /backup/db-$(date +\%Y\%m\%d).sqlWeekly full system backup
0 1 0 /usr/bin/rsync -av --delete /home/ /backup/weekly/Hourly incremental backup during business hours
0 9-17 1-5 /usr/local/bin/incremental-backup.shMonthly offsite backup
0 3 1 /usr/local/bin/upload-to-cloud.sh /backup/monthly/`Monitoring Tasks
`bash
Check disk space every 15 minutes
/15 * /usr/local/bin/check-disk-space.shMonitor service health every 5 minutes
/5 * /usr/local/bin/service-health-check.shGenerate daily system report
0 6 * /usr/local/bin/system-report.sh | mail -s "Daily System Report" admin@example.comWeekly performance analysis
0 0 1 /usr/local/bin/performance-analysis.sh`Application Tasks
`bash
Process pending orders every hour
0 /var/www/app/bin/process-orders.phpGenerate monthly invoices
0 0 1 /var/www/billing/generate-invoices.shClean temporary files every 6 hours
0 /6 /usr/bin/find /var/www/temp -type f -mtime +1 -deleteUpdate search index nightly
0 2 * /var/www/app/bin/update-search-index.sh`Troubleshooting
Common Issues and Solutions
| Issue | Symptoms | Possible Causes | Solutions | |-------|----------|-----------------|-----------| | Job not running | No execution logs | Syntax error, wrong time | Check syntax, verify schedule | | Command not found | Error in logs | PATH issues | Use absolute paths, set PATH | | Permission denied | Access errors | File permissions | Check and fix permissions | | Script fails silently | No output/errors | Missing error handling | Add logging and error checks | | Multiple instances | Resource conflicts | Long-running jobs | Implement job locking |
Debugging Commands
`bash
Check if cron daemon is running
systemctl status cronVerify crontab syntax
crontab -l | cron-validatorTest cron job manually
sudo -u username /path/to/script.shCheck file permissions
ls -la /path/to/script.shVerify PATH and environment
env | grep PATH`Diagnostic Script
`bash
#!/bin/bash
Cron diagnostic script
echo "=== Cron Diagnostic Report ===" echo "Date: $(date)" echo
echo "=== Cron Service Status ===" systemctl status cron echo
echo "=== Current User's Crontab ===" crontab -l 2>/dev/null || echo "No crontab for current user" echo
echo "=== Recent Cron Log Entries ===" tail -20 /var/log/cron echo
echo "=== Environment Variables ===" printenv | sort echo
echo "=== Disk Space ===" df -h echo
echo "=== System Load ==="
uptime
`
Security Considerations
Access Control
| Security Measure | Implementation | Purpose |
|------------------|----------------|---------|
| User restrictions | /etc/cron.allow, /etc/cron.deny | Control who can use cron |
| File permissions | chmod 600 crontab | Protect crontab files |
| Script permissions | chmod 755 script.sh | Secure script execution |
| Directory permissions | chmod 755 /usr/local/bin/ | Control script access |
Secure Practices
`bash
Restrict cron access to specific users
echo "admin" > /etc/cron.allow echo "backup" >> /etc/cron.allowSet secure permissions on scripts
chmod 755 /usr/local/bin/backup-script.sh chown root:root /usr/local/bin/backup-script.shUse dedicated service accounts
sudo -u backupuser crontab -eAvoid storing sensitive data in crontab
Instead, use secure configuration files
0 2 * /usr/local/bin/backup.sh --config /etc/backup/secure.conf`Audit and Monitoring
`bash
Monitor crontab changes
auditctl -w /var/spool/cron/crontabs/ -p wa -k crontab-changesLog all cron job executions
echo "CRON_LOG_LEVEL=info" >> /etc/environmentRegular security review
0 0 1 /usr/local/bin/cron-security-audit.sh`Advanced Features
Job Locking
Prevent multiple instances of the same job from running simultaneously:
`bash
#!/bin/bash
Script with file locking
LOCKFILE="/var/lock/my-script.lock"
Acquire lock or exit
exec 200>"$LOCKFILE" flock -n 200 || { echo "Another instance is running" exit 1 }Your script logic here
echo "Script is running..." sleep 60Lock is automatically released when script exits
`Conditional Execution
`bash
Run only on first Monday of month
0 9 1-7 * 1 /usr/local/bin/first-monday-task.shRun only if file exists
0 2 * [ -f /tmp/run-backup ] && /usr/local/bin/backup.shRun with system load check
/5 * [ $(uptime | awk '{print $10}' | cut -d, -f1) -lt 2 ] && /usr/local/bin/load-sensitive-task.sh`Multi-Server Coordination
`bash
Run on primary server only
0 2 * [ "$(hostname)" = "primary-server" ] && /usr/local/bin/primary-task.shDistributed job execution
0 /6 /usr/local/bin/distributed-task.sh --node $(hostname)Failover mechanism
0 2 * /usr/local/bin/check-primary.sh || /usr/local/bin/failover-task.sh`Integration with Configuration Management
`bash
Ansible managed crontab entry
This file is managed by Ansible - do not edit manually
0 2 * /usr/local/bin/ansible-managed-backup.shChef managed cron job
Generated by Chef cookbook: backup_system v1.2.3
0 3 * /opt/chef/bin/backup-runner.sh`Cron remains an essential tool for system automation and task scheduling. Understanding its syntax, capabilities, and best practices enables administrators and developers to create reliable, maintainable scheduled task systems that form the backbone of automated operations in Unix-like environments.