Automating Recurring Tasks with Cron on Linux
Understanding the Cron Service
The crond daemon manages scheduled command execution on Linux systems. It scans three locations every minute to determine which jobs should run:
/etc/crontab: The primary system-wide crontab, typically used by administrators for maintenance routines./etc/cron.d/: A directory containing individual crontab files or scripts that require precise scheduling./var/spool/cron/: Stores per-user crontab files. Each file is named after the corresponding user (e.g.,/var/spool/cron/tom). A user may have at most one crontab entry here.
The crontab utility is the standard interface for editing user-level schedules. Running crontab -e modifies the current user's job definitions. When editing system crontabs manually (like /etc/crontab), you must include the user feild to specify under which account the command executes.
Four additional directories simplify recurring jobs at fixed intervals:
/etc/cron.hourly//etc/cron.daily//etc/cron.weekly//etc/cron.monthly/
These directories only become active when referenced by an entry in /etc/crontab or a file under /etc/cron.d/. Without that linkage, scripts placed inside them are ignored.
Permissions and Access Control
The directory /var/spool/cron/ is owned by root with permissions 700. However, becauce the crontab binary carries the SUID bit, regular users can still manage their own schedules. Root governs access through two optional files:
/etc/cron.allow– If present, only listed users may usecrontab./etc/cron.deny– Checked only ifcron.allowis absent; listed users are blocked.
When both files exist, cron.allow takes precedence. If neither file is present, only root retains scheduling privileges. An empty cron.deny file permits every user to run crontab.
Crontab Syntax
Each line in a crontab follows this pattern:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,...
# | | | | .---- day of week (0 - 6) (Sunday = 0 or 7) OR sun,mon,tue,...
# | | | | |
# * * * * * user-name command
Matching Rules
A job triggers when the current minute, hour, and month match, and at least one of the two day fields (day of month, day of week) matches. If both day fields are "restricted" (no * wildcard), the condition is satisfied when either field matches—an OR relationship. Otherwise, the fields act as an AND filter.
Examples
# Switch to bash instead of the default shell
SHELL=/bin/bash
# Fire at 22:00 and 23:00, Monday through Friday
0 22,23 * * 1-5 echo "Weekday late evening task"
# Run at minute 23 past every second hour, all day
23 0-23/2 * * * echo "Bi-hourly job, 23 minutes after the hour"
# Every second Saturday of the month at 04:00
0 4 8-14 * * test $(date +\%u) -eq 6 && echo "Second Saturday"
# On the 1st of any month AND every Monday, every 4 hours
0 */4 1 * mon echo "First day or Monday, 4-hour interval"
# At midnight on Sundays that fall on odd-numbered dates
0 0 */2 * sun echo "Midnight, odd-date Sundays"
For the entry 0 */4 1 * mon, the 1st day of the month and Monday form an OR condition. In 0 0 */2 * sun, odd-numbered dates and Sunday together form an AND condition.
Further Details
Refer to man 5 crontab for the complete specification, including environment variable handling, special strings like @reboot, and additional time patterns.