Last modified: October 11, 2024

This article is written in: πŸ‡ΊπŸ‡Έ

Cron

Cron is a powerful utility in Unix-like operating systems that automates the execution of scripts or commands at specified times, dates, or intervals. It's an essential tool for system administrators and users alike, facilitating tasks such as system maintenance, backups, updates, and more.

How Cron Works

Cron operates through a background process called the cron daemon (crond), which continuously runs and checks for scheduled tasks in crontab files. When the current time matches a scheduled time in the crontab, the cron daemon executes the associated command or script.

Workflow Diagram:

+---------------------------------------------------+
|                                                   |
|             Cron Workflow Overview                |
|                                                   |
+---------------------------------------------------+

User/System Schedules Tasks
          β”‚
          β–Ό
+----------------+      +-------------------+
|                |      |                   |
|  Cron Daemon   |----->|  Crontab Files    |
|   (crond)      |      |                   |
|                |      +-------------------+
|  (Runs Every   |               β”‚
|   Minute)      |               β–Ό
|                |      +-------------------+
+----------------+      |                   |
                        |  Executes Tasks   |
                        |  at Scheduled     |
                        |  Times            |
                        |                   |
                        +-------------------+

Types of Crontab Files

Cron uses two main types of crontab files to schedule tasks:

System Crontabs

For example, to schedule the apt update command to run as the root user every hour on the hour, use the cron job entry:

# m h dom mon dow user  command
0 * * * *   root  /usr/bin/apt update

User Crontabs

Understanding Crontab Syntax

A crontab file consists of lines with six fields: five time fields and a command field.

Crontab Field Structure

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ Minute (0 - 59)
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ Hour (0 - 23)
β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ Day of Month (1 - 31)
β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ Month (1 - 12 or Jan-Dec)
β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ Day of Week (0 - 7 or Sun-Sat)
β”‚ β”‚ β”‚ β”‚ β”‚
* * * * * command_to_execute

Field Descriptions

Field Values
Minute 0 to 59
Hour 0 to 23
Day of Month 1 to 31
Month 1 to 12 or abbreviated month names (Jan, Feb, etc.)
Day of Week 0 to 7 (both 0 and 7 are Sunday) or abbreviated day names (Sun, Mon, etc.)

Special Characters

Symbol Description
Asterisk (*) Represents all possible values for a field.
Comma (,) Separates multiple values.
Hyphen (-) Defines a range.
Slash (/) Specifies step values.

Examples

I. Run a command every day at 2:00 AM:

0 2 * * * /path/to/command

II. Run a script at 1:00 PM on Tuesdays, Wednesdays, and Thursdays:

0 13 * * 2-4 /path/to/script.sh

III. Execute a backup at 7:30 AM from Monday to Friday:

30 7 * * 1-5 /path/to/backup.sh

IV. Run a task at 10:15 PM on the 1st of every month:

15 22 1 * * /path/to/monthly_task.sh

V. Execute a script at midnight on January 1st every year:

0 0 1 1 * /path/to/new_year_script.sh

VI. Run a command every 5 minutes:

*/5 * * * * /path/to/command

Visualizing Time Fields

Here's an ASCII table to help visualize how the time fields correspond to scheduling:

+-----------+-----------+--------------+--------------+-----------------+
|  Field    |   Value   |    Allowed   |     Step     |      Notes      |
+-----------+-----------+--------------+--------------+-----------------+
| Minute    |     M     |     0-59     |     /n       | * for every min |
| Hour      |     H     |     0-23     |     /n       | * for every hr  |
| Day of    |    DOM    |     1-31     |     /n       | * for every day |
| Month     |     M     |     1-12     |     /n       | * for every mo  |
| Day of    |    DOW    |     0-7      |     /n       | 0 or 7 = Sunday |
+-----------+-----------+--------------+--------------+-----------------+

Cron Directories for Regular Intervals

For tasks that need to run at regular intervals without custom scheduling, cron provides specific directories:

/etc/cron.hourly/
β”œβ”€β”€ task1
β”œβ”€β”€ task2
└── ...

/etc/cron.daily/
β”œβ”€β”€ task1
β”œβ”€β”€ task2
└── ...

/etc/cron.weekly/
β”œβ”€β”€ task1
β”œβ”€β”€ task2
└── ...

/etc/cron.monthly/
β”œβ”€β”€ task1
β”œβ”€β”€ task2
└── ...

Directory Description
/etc/cron.hourly/ Place scripts here to run every hour.
/etc/cron.daily/ Scripts run once daily.
/etc/cron.weekly/ Scripts execute once a week.
/etc/cron.monthly/ Scripts run once a month.

How These Directories Work

The system crontab (/etc/crontab) includes entries that trigger the execution of scripts in these directories.

Example entry from /etc/crontab:

# Run hourly jobs
01 * * * * root run-parts /etc/cron.hourly

run-parts is a utility that executes all scripts in the specified directory.

Creating Custom Schedules with Crontab

To schedule tasks at specific times, you can create custom crontab entries.

Editing the Crontab File

Open the crontab editor:

crontab -e

Add your scheduled tasks using the crontab syntax.

Example: Append a Message Every 15 Minutes

To add "15 minutes have elapsed" to a log file every 15 minutes:

*/15 * * * * echo "15 minutes have elapsed" >> /path/to/your/timer.log

Using Environment Variables

You can set environment variables in your crontab:

PATH=/usr/local/bin:/usr/bin:/bin

Advanced Scheduling Techniques

Using Step Values

Use */N to run a task every N units of time.

Run a script every 3 hours:

0 */3 * * * /path/to/script.sh

Specific Days and Times

I. Use commas to separate days.

Run a task on Mondays, Wednesdays, and Fridays:

0 9 * * 1,3,5 /path/to/task.sh

II. Combine ranges and steps.

Run a command every 2 hours between 8 AM and 4 PM:

0 8-16/2 * * * /path/to/command

Special Strings

Cron allows the use of special strings instead of the five time fields:

Schedule Description
@reboot Run once at startup.
@yearly or @annually Run once a year (0 0 1 1 *).
@monthly Run once a month (0 0 1 * *).
@weekly Run once a week (0 0 * * 0).
@daily or @midnight Run once a day (0 0 * * *).
@hourly Run once an hour (0 * * * *).

For example, to schedule the script weekly_task.sh to run every week, use the cron job entry:

@weekly /path/to/weekly_task.sh

Managing Cron Allow and Deny

Editing System-Wide Crontab

For example, to run the system_backup.sh script as the root user every day at 2:30 AM, use the cron job entry:

# m h dom mon dow user  command
30 2 * * * root /usr/local/bin/system_backup.sh

Example Scenarios

Scenario 1: Database Backup

Backup a database every night at 11:30 PM.

30 23 * * * /usr/local/bin/backup_database.sh >> /var/log/db_backup.log 2>&1

Scenario 2: Clear Cache Weekly

Clear application cache every Sunday at 3:00 AM.

0 3 * * 0 /usr/bin/php /var/www/html/app/clear_cache.php

Scenario 3: System Update

Run system updates on the 1st and 15th of every month at 4:00 AM.

0 4 1,15 * * /usr/bin/apt update && /usr/bin/apt upgrade -y

Best Practices

Use Absolute Paths

Always specify the full path to commands and scripts.

0 2 * * * /usr/bin/python3 /home/user/scripts/backup.py

Redirect Output

0 2 * * * /path/to/command >> /var/log/command.log 2>&1

Environment Variables

Cron runs with a minimal environment. If your command depends on certain variables, define them in the crontab or within your script.

For example, to run script.sh every day at 5:00 AM using the Bash shell and specifying the PATH environment, set the cron job as follows:

SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin

0 5 * * * /path/to/script.sh

Test Your Commands

Before adding them to the crontab, test your commands in the terminal to ensure they work as expected.

Monitoring and Logging

Avoid Overlapping Jobs

For tasks that may take longer than the scheduling interval, prevent overlapping executions.

This script example ensures that only one instance of the script can run at a time by using a file lock. Here’s how it works:

#!/bin/bash
(
  flock -n 9 || exit 1
  # Your script commands go here
) 9>/var/lock/.myscript.exclusive

Common Pitfalls

For further exploration and to test cron expressions, consider using online tools like Crontab Guru. Always refer to the man pages (man cron, man crontab) for comprehensive documentation.

Challenges

  1. List the contents of the /etc/cron.d directory to identify any system-defined cron jobs. Examine the structure and contents of a few files using cat or less to understand how these jobs are defined. Reflect on the purpose of each file and how it might be used for system maintenance.
  2. Explore the scripts located in /etc/cron.monthly and choose a few to examine with cat. For each script, determine what task it performs and hypothesize why it might be scheduled on a monthly basis. Consider what types of tasks benefit from monthly scheduling as you explore.
  3. Given the cron schedule 0 2 * * *, determine the exact time and frequency this job runs. Write down your interpretation of each field in the cron expression, and explain how you arrived at the conclusion that this job runs at 2:00 AM daily.
  4. For the cron schedule 0 13 * * 2-4, determine the days of the week and the time this job is scheduled to run. Break down each field of the cron expression, then test your understanding by translating it into a human-readable schedule (e.g., "every Tuesday through Thursday at 1:00 PM").
  5. Write a shell script that appends the message β€œ15 minutes have elapsed” to a log file located at ~/your_timer.log. Schedule this script using crontab -e to run every 15 minutes. Verify your setup by giving the script executable permissions, waiting for it to run, and then checking the log file to confirm it’s working as intended.
  6. Use crontab -l to view all your active cron jobs and locate the one created in the previous challenge. Then, remove all cron jobs using crontab -r and confirm the deletion with crontab -l. Document what happens when you remove all cron jobs and the implications for your scheduled tasks.
  7. Modify the script from challenge 5 to include error handling: if the script cannot write to ~/your_timer.log (e.g., due to permission issues), it should log an error message to ~/your_timer_error.log. Test the script by temporarily changing permissions to simulate an error, then check both log files to see the results.
  8. Investigate the use of special cron characters such as *, ,, -, and / to build more complex schedules. Create a new cron job that runs every 5 minutes during the first 15 minutes of each hour (e.g., at :00, :05, and :10 of each hour). Use crontab -l to confirm the job is correctly defined.
  9. Research cron’s ability to send output and error messages to a specific email address. Configure a test cron job that sends an email notification to a chosen address each time it runs. You may need to adjust your cron configuration and ensure a mail utility is set up on your system. Test the setup by checking your email after the job runs.
  10. Create a cron job that performs a conditional task based on the system’s uptime. Write a script that checks the uptime, and if it’s greater than 24 hours, appends a message to a log file. Schedule this script to run hourly. Test the job by adjusting the script to simulate various uptime values and checking the log file for accuracy.

Table of Contents

    Cron
    1. How Cron Works
    2. Types of Crontab Files
      1. System Crontabs
      2. User Crontabs
    3. Understanding Crontab Syntax
      1. Crontab Field Structure
      2. Field Descriptions
      3. Special Characters
      4. Examples
      5. Visualizing Time Fields
    4. Cron Directories for Regular Intervals
      1. How These Directories Work
    5. Creating Custom Schedules with Crontab
      1. Editing the Crontab File
      2. Example: Append a Message Every 15 Minutes
      3. Using Environment Variables
    6. Advanced Scheduling Techniques
      1. Using Step Values
      2. Specific Days and Times
      3. Special Strings
      4. Managing Cron Allow and Deny
      5. Editing System-Wide Crontab
    7. Example Scenarios
      1. Scenario 1: Database Backup
      2. Scenario 2: Clear Cache Weekly
      3. Scenario 3: System Update
    8. Best Practices
      1. Use Absolute Paths
      2. Redirect Output
      3. Environment Variables
      4. Test Your Commands
      5. Monitoring and Logging
      6. Avoid Overlapping Jobs
    9. Common Pitfalls
    10. Challenges