Last modified: June 01, 2025
This article is written in: πΊπΈ
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 is used for tasks such as system maintenance, backups, updates, and more.
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.
+------------------------------------------------------------------+
| Cron Workflow Overview |
+------------------------------------------------------------------+
β
βΌ
+--------------------------------------+ +----------------------------------+
| User/System Schedules | | Crontab Files |
| Tasks/Commands | | (Contains timing & task details)|
| (Via command line or configuration) | | |
+--------------------------------------+ +----------------------------------+
β β
β (Updates/reads scheduled tasks) β
--------------------------------------------------------
|
βΌ
+-------------------------------+
| Cron Daemon (crond) |
| (Executes every minute) |
+-------------------------------+
β
β Monitors timing schedules and
β triggers corresponding tasks
βΌ
+---------------------------------+
| Executes Scheduled Tasks |
| (Runs user/system-defined jobs) |
+---------------------------------+
Cron uses two main types of crontab files to schedule tasks:
/etc/crontab
root
user) for system-wide tasks.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
/var/spool/cron/crontabs/
, although this location can vary depending on the system configuration.crontab -e
, which opens the crontab file for modification.crontab -l
, which displays the current contents of their crontab file.crontab -r
, deleting all scheduled tasks at once.A crontab file consists of lines with six fields: five time fields and a command field.
ββββββββββββββ 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 | 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.) |
Symbol | Description |
Asterisk (* ) |
Represents all possible values for a field. |
Comma (, ) |
Separates multiple values. |
Hyphen (- ) |
Defines a range. |
Slash (/ ) |
Specifies step values. |
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
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 |
+-----------+-----------+--------------+--------------+-----------------+
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. |
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.
To schedule tasks at specific times, you can create custom crontab entries.
Open the crontab editor:
crontab -e
Add your scheduled tasks using the crontab syntax.
To add "15 minutes have elapsed" to a log file every 15 minutes:
*/15 * * * * echo "15 minutes have elapsed" >> /path/to/your/timer.log
You can set environment variables in your crontab:
PATH=/usr/local/bin:/usr/bin:/bin
Use */N
to run a task every N units of time.
Run a script every 3 hours:
0 */3 * * * /path/to/script.sh
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
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
/etc/cron.allow
file is used to specify which users are allowed to access and use the cron service for scheduling tasks./etc/cron.deny
file lists users who are explicitly denied permission to use cron for task automation./etc/cron.d/
.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
Backup a database every night at 11:30 PM.
30 23 * * * /usr/local/bin/backup_database.sh >> /var/log/db_backup.log 2>&1
Clear application cache every Sunday at 3:00 AM.
0 3 * * 0 /usr/bin/php /var/www/html/app/clear_cache.php
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
Always specify the full path to commands and scripts.
0 2 * * * /usr/bin/python3 /home/user/scripts/backup.py
>
symbol is used to overwrite the contents of a file, while >>
is used to append output to an existing file without overwriting it.2>
operator is used to overwrite the error output to a file, while 2>>
appends the error output to the file instead of overwriting it.For example, to execute /path/to/command
every day at 2:00 AM and direct both standard output and error output to a log file, use the cron job entry:
0 2 * * * /path/to/command >> /var/log/command.log 2>&1
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
Before adding them to the crontab, test your commands in the terminal to ensure they work as expected.
/var/log/cron
, /var/log/syslog
, or /var/log/messages
.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
flock -n 9
attempts to acquire an exclusive, non-blocking lock on file descriptor 9. If the lock cannot be acquired because another instance is running, it immediately exits with exit 1
.9>/var/lock/.myscript.exclusive
specifies the lock file. This file is used to track the lock status; if itβs locked, another instance will not start.chmod +x script.sh
).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.
/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.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.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").~/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.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.~/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.*
, ,
, -
, 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.