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

🧠 Test Your Knowledge

What does the cron pattern "0 */6 * * *" mean?