Table of Contents
- Understanding Cron: The Time-Based Scheduler
- Cron Syntax Demystified
- Creating Effective Shell Scripts for Scheduling
- Managing Cron Jobs
- Common Use Cases
- Best Practices for Reliable Scheduling
- Troubleshooting Cron Jobs
- Conclusion
- References
Understanding Cron: The Time-Based Scheduler
Cron is a daemon (background service) that runs continuously on Unix-like systems, executing scheduled tasks (called “cron jobs”) at specified intervals. It reads configuration files called “crontabs” (cron tables) that define when and which commands to run.
Key Components:
- cron daemon: The background process (
cronorcrond) that checks crontabs and executes jobs. - crontab: A text file containing job schedules. Each user (and the system) can have its own crontab.
- cron jobs: Individual entries in a crontab that specify a command/script and a schedule.
Cron Syntax Demystified
A crontab entry has the following structure (with 5 or 6 fields, depending on the type of crontab):
# For user crontabs (no user field):
* * * * * command/to/execute
# For system crontabs (e.g., /etc/crontab):
* * * * * user command/to/execute
Time Fields Explained:
The first five fields define the schedule. Here’s what each represents:
| Field | Range | Description |
|---|---|---|
| Minute | 0–59 | Minute of the hour |
| Hour | 0–23 | Hour of the day (24-hour format) |
| Day of Month | 1–31 | Day of the month |
| Month | 1–12 (or Jan–Dec) | Month of the year |
| Day of Week | 0–6 (0=Sunday, 6=Saturday; or Sun–Sat) | Day of the week |
Special Characters:
Cron supports special characters to simplify scheduling:
| Character | Meaning | Example |
|---|---|---|
* | Wildcard (matches all values) | * * * * * → Every minute |
*/n | ”Every n units” (step interval) | */15 * * * * → Every 15 minutes |
- | Range of values | 10-15 * * * * → Minutes 10–15 |
, | List of values | 0,15,30,45 * * * * → Every 15 minutes |
@ | Predefined shortcuts (non-standard) | @daily → Equivalent to 0 0 * * * |
Predefined Shortcuts (@):
Some systems support these for common intervals:
@reboot: Run once at system startup@daily/@midnight: 00:00 daily (0 0 * * *)@weekly: Sunday 00:00 (0 0 * * 0)@monthly: 1st of month 00:00 (0 0 1 * *)@yearly/@annually: Jan 1st 00:00 (0 0 1 1 *)
Example Cron Schedules:
# Run at 3:15 AM daily
15 3 * * * /path/to/script.sh
# Run every 30 minutes on weekdays (Mon–Fri)
*/30 * * * 1-5 /path/to/monitor.sh
# Run on the 1st and 15th of every month at 2 PM
0 14 1,15 * * /path/to/report.sh
# Run at 10 PM every Saturday
0 22 * * 6 /path/to/backup.sh
# Run at system startup
@reboot /path/to/startup-script.sh
Creating Effective Shell Scripts for Scheduling
Cron jobs often execute shell scripts, which contain the logic for the task. A well-written script ensures reliability, ease of debugging, and maintainability. Below are key principles for creating scripts intended for cron.
1. Start with a Shebang
Always specify the shell interpreter with a shebang line at the top:
#!/bin/bash
2. Enable Strict Error Handling
Use set options to make the script exit on errors and undefined variables:
#!/bin/bash
set -euo pipefail # Exit on error, undefined var, or pipe failure
-e: Exit immediately if a command fails.-u: Treat undefined variables as errors.-o pipefail: Exit if any command in a pipeline fails.
3. Use Absolute Paths
Cron runs with a minimal environment (e.g., limited PATH). Always use absolute paths for files, commands, and scripts:
# Bad: Relies on PATH
rsync -av /data /backup
# Good: Absolute path
/usr/bin/rsync -av /home/user/data /mnt/backup/daily
4. Log Output
Cron jobs don’t have a terminal, so log output to a file for debugging:
LOG_FILE="/var/log/daily-backup.log"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Backup started" >> "$LOG_FILE"
5. Define Variables for Reusability
Centralize configurable values (e.g., paths, thresholds) as variables:
SOURCE_DIR="/home/user/documents"
DEST_DIR="/mnt/backup/documents"
RETENTION_DAYS=7 # Keep backups for 7 days
Example: Daily Backup Script
#!/bin/bash
set -euo pipefail
# Configuration
SOURCE_DIR="/home/user/important-files"
DEST_DIR="/mnt/backup/daily"
LOG_FILE="/var/log/daily-backup.log"
RETENTION_DAYS=7
# Log start
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Starting backup..." >> "$LOG_FILE"
# Create destination if it doesn't exist
mkdir -p "$DEST_DIR" >> "$LOG_FILE" 2>&1
# Perform backup with rsync
/usr/bin/rsync -av --delete "$SOURCE_DIR"/ "$DEST_DIR"/ >> "$LOG_FILE" 2>&1
# Prune old backups (keep last 7 days)
find "$DEST_DIR" -type f -mtime +"$RETENTION_DAYS" -delete >> "$LOG_FILE" 2>&1
# Log completion
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Backup completed successfully" >> "$LOG_FILE"
Managing Cron Jobs
Editing Crontabs
To manage your user crontab, use the crontab command:
crontab -e: Edit your crontab (opens in the default editor, e.g.,nanoorvim).crontab -l: List your current crontab entries.crontab -r: Delete your crontab (use with caution!).
Example User Crontab Entry
To schedule the backup script above to run daily at 2 AM:
# Edit crontab
crontab -e
# Add this line (then save and exit)
0 2 * * * /home/user/scripts/daily-backup.sh
System-Wide Cron Jobs
For tasks that run as root or affect the entire system, use:
/etc/crontab: System-wide crontab with auserfield (e.g.,0 3 * * * root /path/to/script.sh)./etc/cron.d/: Directory for custom system crontabs (e.g.,/etc/cron.d/backup-job).
Environment Variables in Cron
Cron’s environment is minimal (e.g., PATH=/usr/bin:/bin). To set variables, define them in the crontab or script:
# In crontab: Set PATH and MAILTO
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
MAILTO="[email protected]" # Send output to this email
0 2 * * * /home/user/scripts/daily-backup.sh
Common Use Cases
1. Log Rotation
Compress and archive old logs to save disk space:
# Cron entry: Run daily at 1 AM
0 1 * * * /usr/local/bin/rotate-logs.sh
2. Database Backups
Dump a MySQL database and upload to cloud storage:
# Cron entry: Run weekly on Sunday at 3 AM
0 3 * * 0 /home/admin/scripts/mysql-backup.sh
3. System Monitoring
Check disk space and alert if usage exceeds 90%:
# Cron entry: Run every 6 hours
0 */6 * * * /usr/local/bin/check-disk-space.sh
4. Cleanup Tasks
Delete temporary files older than 30 days:
# Cron entry: Run monthly on the 1st at midnight
0 0 1 * * /usr/local/bin/cleanup-tmp.sh
Best Practices for Reliable Scheduling
1. Test Scripts Manually First
Always run scripts manually before scheduling them to ensure they work as expected:
bash /home/user/scripts/daily-backup.sh # Test the backup script
2. Restrict Permissions
- Make scripts executable but not world-writable:
chmod 700 /home/user/scripts/daily-backup.sh # Read/write/execute for owner only - Store scripts in a secure directory (e.g.,
/usr/local/binfor system scripts).
3. Avoid Overloading the System
Schedule resource-intensive jobs (e.g., large backups) during off-peak hours (e.g., midnight–4 AM).
4. Comment Crontabs
Add comments to explain the purpose of each job:
# Daily backup of user documents (2 AM)
0 2 * * * /home/user/scripts/daily-backup.sh
5. Version Control Scripts
Store shell scripts in Git for tracking changes and rollbacks:
git add /home/user/scripts/daily-backup.sh
git commit -m "Add retention policy to backup script"
Troubleshooting Cron Jobs
If a cron job isn’t running as expected, use these steps to diagnose issues:
1. Check if Cron is Running
Ensure the cron daemon is active:
systemctl status cron # On systemd systems (Ubuntu, Debian)
# or
service crond status # On SysVinit systems (RHEL, CentOS)
2. Inspect Cron Logs
Cron logs activity to system logs (e.g., /var/log/syslog on Debian/Ubuntu):
grep CRON /var/log/syslog # Check if the job ran
3. Verify Script Permissions
Ensure the script is executable and the cron user has read access:
ls -l /home/user/scripts/daily-backup.sh # Should show -rwx------ or similar
4. Debug Script Output
Check the script’s log file for errors:
tail -f /var/log/daily-backup.log # Monitor the backup log
5. Validate Cron Syntax
Use crontab -l to check for typos, or online tools like Cronitor to validate schedules.
Conclusion
Cron and shell scripts are foundational tools for automating repetitive tasks in Unix-like systems. By mastering cron syntax, writing robust shell scripts, and following best practices (e.g., logging, absolute paths, testing), you can build reliable automation pipelines to save time and reduce errors.
Whether you’re managing a personal server or a enterprise environment, the ability to schedule jobs effectively is a critical skill. Start small—automate a daily backup or log cleanup—and gradually expand to more complex workflows. With practice, you’ll unlock the full potential of cron and shell scripts for seamless system administration.
References
- crontab(5) - Linux Manual Page
- GNU Bash Manual
- Ubuntu Cron Documentation
- Cron Best Practices - DigitalOcean
- Shell Scripting Best Practices - Google