Bash Schedule (cron)
Automating tasks with scheduled scripts
⏰ What is Cron?
Cron is a time-based job scheduler in Unix-like systems. It runs scripts and commands automatically at specified times, dates, or intervals, perfect for backups, maintenance, and repetitive tasks without manual intervention.
# Edit crontab
crontab -e
# Run script every day at 2 AM
0 2 * * * /path/to/script.sh
Result:
Script will execute daily at 2:00 AM
Cron Concepts
Crontab
Schedule configuration file
crontab -e
Time Format
Minute Hour Day Month Weekday
* * * * *
Intervals
Repeat at specific times
*/5 * * * *
Commands
Scripts to execute
command or /path/script.sh
🔹 Cron Time Format
Cron schedules are defined by five time-and-date fields: minute (0-59), hour (0-23), day of month (1-31), month (1-12), and day of week (0-7, where 0 and 7 are Sunday). Each field can be a specific number, a range (1-5), a list (1,3,5), a step value (*/15), or an asterisk (*) for "any". Understanding this compact syntax is essential for accurately scheduling tasks to run at the desired intervals, from every minute to once a year.
# Cron time format:
# * * * * * command
# │ │ │ │ │
# │ │ │ │ └─── Day of week (0-7, Sun=0 or 7)
# │ │ │ └───── Month (1-12)
# │ │ └─────── Day of month (1-31)
# │ └───────── Hour (0-23)
# └─────────── Minute (0-59)
# Examples:
# Every minute
* * * * * /path/to/script.sh
# Every hour at minute 30
30 * * * * /path/to/script.sh
# Every day at 3:15 AM
15 3 * * * /path/to/script.sh
# Every Monday at 9:00 AM
0 9 * * 1 /path/to/script.sh
# First day of every month at midnight
0 0 1 * * /path/to/script.sh
Format Breakdown:
Field Values Special Characters ----- ------ ------------------ Minute 0-59 * , - / Hour 0-23 * , - / Day 1-31 * , - / Month 1-12 * , - / Weekday 0-7 * , - /
🔹 Common Cron Schedules
Common cron patterns provide templates for standard scheduling needs. Run every minute: * * * * *. Daily at 2 AM: 0 2 * * *. Weekly on Sunday at midnight: 0 0 * * 0. Monthly on the 1st at noon: 0 12 1 * *. Every weekday at 9 AM: 0 9 * * 1-5. Every 10 minutes: */10 * * * *. These patterns serve as a starting point that you can customize for specific hours, days, or intervals.
# Every 5 minutes
*/5 * * * * /path/to/script.sh
# Every 15 minutes
*/15 * * * * /path/to/script.sh
# Every hour
0 * * * * /path/to/script.sh
# Every day at midnight
0 0 * * * /path/to/script.sh
# Every day at 6:30 AM
30 6 * * * /path/to/script.sh
# Every Sunday at 2:00 AM
0 2 * * 0 /path/to/script.sh
# Every weekday at 8:00 AM
0 8 * * 1-5 /path/to/script.sh
# Every month on the 1st at 3:00 AM
0 3 1 * * /path/to/script.sh
# Every 6 hours
0 */6 * * * /path/to/script.sh
# Twice a day (6 AM and 6 PM)
0 6,18 * * * /path/to/script.sh
Schedule Examples:
Pattern Description ------- ----------- */5 * * * * Every 5 minutes 0 * * * * Every hour 0 0 * * * Daily at midnight 0 2 * * 0 Weekly on Sunday 2 AM 0 3 1 * * Monthly on 1st at 3 AM 0 8 * * 1-5 Weekdays at 8 AM
🔹 Managing Crontab
The crontab command is your interface for managing scheduled jobs in a user-specific file. Use crontab -e to edit your jobs in the default editor. List current jobs with crontab -l. Remove all jobs with crontab -r (use cautiously). Each user has their own crontab file (usually in /var/spool/cron/), ensuring schedules are isolated and run with appropriate user permissions. Always double-check syntax after editing.
# Edit crontab (opens in default editor)
crontab -e
# List current cron jobs
crontab -l
# Remove all cron jobs
crontab -r
# Edit crontab for specific user (requires sudo)
sudo crontab -u username -e
# List another user's crontab
sudo crontab -u username -l
# Example crontab file content:
# Backup database every day at 1 AM
0 1 * * * /home/user/backup.sh
# Clean temp files every Sunday at 3 AM
0 3 * * 0 /home/user/cleanup.sh
# Send report every weekday at 9 AM
0 9 * * 1-5 /home/user/report.sh
# Check disk space every 2 hours
0 */2 * * * /home/user/check-disk.sh
Crontab Commands:
Command Description ------- ----------- crontab -e Edit crontab crontab -l List cron jobs crontab -r Remove all jobs crontab -u user -e Edit user's crontab
🔹 Special Cron Strings
Cron supports readable shortcut strings for common schedules, prefixed with @. @reboot runs once at system startup. @yearly or @annually runs at 00:00 on January 1st. @monthly on the 1st of each month. @weekly on Sunday at midnight. @daily or @midnight at 00:00 daily. @hourly at the beginning of each hour. These strings improve crontab readability and reduce syntax errors.
# Run at system startup
@reboot /path/to/startup-script.sh
# Run once a year (January 1st, midnight)
@yearly /path/to/yearly-task.sh
# Same as: 0 0 1 1 *
# Run once a month (1st day, midnight)
@monthly /path/to/monthly-task.sh
# Same as: 0 0 1 * *
# Run once a week (Sunday, midnight)
@weekly /path/to/weekly-task.sh
# Same as: 0 0 * * 0
# Run once a day (midnight)
@daily /path/to/daily-task.sh
# Same as: 0 0 * * *
# Run once an hour
@hourly /path/to/hourly-task.sh
# Same as: 0 * * * *
# Example usage
@reboot /home/user/start-services.sh
@daily /home/user/backup.sh
@weekly /home/user/cleanup.sh
Special Strings:
String Equivalent Description ------ ---------- ----------- @reboot - At startup @yearly 0 0 1 1 * Once a year @monthly 0 0 1 * * Once a month @weekly 0 0 * * 0 Once a week @daily 0 0 * * * Once a day @hourly 0 * * * * Once an hour
🔹 Cron Script Best Practices
Scripts intended for cron require specific considerations to run reliably in a non-interactive environment. Always use absolute paths for commands and files, as cron's PATH is minimal. Make scripts executable (chmod +x). Test scripts manually in a shell mimicking cron's environment (e.g., env -i /bin/bash). Redirect all output (stdout and stderr) to log files for debugging. These steps prevent common issues like "command not found" errors or silent failures.
#!/bin/bash
# backup.sh - Example cron script
# Use absolute paths
BACKUP_DIR="/home/user/backups"
SOURCE_DIR="/home/user/data"
LOG_FILE="/home/user/logs/backup.log"
# Create timestamp
DATE=$(date +%Y%m%d_%H%M%S)
# Log start time
echo "[$DATE] Backup started" >> "$LOG_FILE"
# Perform backup
tar -czf "$BACKUP_DIR/backup_$DATE.tar.gz" "$SOURCE_DIR" 2>> "$LOG_FILE"
# Check if successful
if [ $? -eq 0 ]; then
echo "[$DATE] Backup completed successfully" >> "$LOG_FILE"
else
echo "[$DATE] Backup failed" >> "$LOG_FILE"
fi
# Delete old backups (keep last 7 days)
find "$BACKUP_DIR" -name "backup_*.tar.gz" -mtime +7 -delete
# Crontab entry for this script:
# Run backup every day at 2 AM
# 0 2 * * * /home/user/backup.sh
Best Practices:
✓ Use absolute paths for all commands ✓ Redirect output to log files ✓ Make scripts executable (chmod +x) ✓ Test scripts manually first ✓ Include error handling ✓ Add timestamps to logs ✓ Set proper environment variables ✓ Use meaningful script names
🔹 Cron Environment and Logging
Cron executes jobs in a stripped-down environment, which often lacks user-specific variables. Set necessary environment variables (like PATH, HOME) at the top of your crontab or within the script. For logging, use redirection: * * * * * /script.sh >> /path/to/log 2>&1 appends both output and errors. Use [email protected] to receive email alerts for job output. Proper environment setup and logging are crucial for monitoring and debugging automated tasks.
# Set environment variables in crontab
SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin
[email protected]
# Redirect output to log file
0 2 * * * /path/to/script.sh >> /path/to/logfile.log 2>&1
# Redirect only errors
0 2 * * * /path/to/script.sh 2>> /path/to/error.log
# Discard all output
0 2 * * * /path/to/script.sh > /dev/null 2>&1
# Send output via email (if MAILTO is set)
0 2 * * * /path/to/script.sh
# Example with environment variables
HOME=/home/user
PATH=/usr/local/bin:/usr/bin:/bin
SHELL=/bin/bash
# Backup with logging
0 1 * * * /home/user/backup.sh >> /home/user/logs/backup.log 2>&1
# Cleanup with error logging
0 3 * * 0 /home/user/cleanup.sh 2>> /home/user/logs/error.log
# Monitor with email notification
*/30 * * * * /home/user/monitor.sh
Output Redirection:
Syntax Description ------ ----------- > file Redirect stdout to file 2> file Redirect stderr to file >> file Append stdout to file 2>&1 Redirect stderr to stdout > /dev/null 2>&1 Discard all output