Skip to main content

cron

cron is a time-based job scheduler daemon that executes commands at specified intervals. Jobs are defined in crontab files using a five-field time syntax (minute, hour, day, month, weekday). It is the standard mechanism for backups, log rotation, and scheduled maintenance.

Understanding cron

What Is cron in Simple Terms

cron is the Linux alarm clock for automated tasks. You tell it what to run and when, and it runs that command at exactly that time, every time, whether you are logged in or not. Backup at 1 AM every night: cron. Certificate renewal every 90 days: cron. Log cleanup every Sunday: cron.

How It Works

◈ DIAGRAM
+------------------------------------------+
| crond daemon (runs continuously) |
| Wakes up every minute |
| Checks all crontab files |
+------------------------------------------+
|
match found
|
v
+------------------------------------------+
| Fork a child process |
| Set minimal environment |
| PATH=/usr/bin:/bin only |
| Execute the command as specified user |
+------------------------------------------+
|
v
+------------------------------------------+
| Command output: emailed to user |
| (unless redirected with >> logfile 2>&1) |
+------------------------------------------+

Crontab time field syntax:

◈ DIAGRAM
+---------- minute (0-59)
| +-------- hour (0-23)
| | +------ day of month (1-31)
| | | +---- month (1-12)
| | | | +-- day of week (0=Sun, 6=Sat)
| | | | |
* * * * * command to execute
Special values:
* every value
*/15 every 15 units (*/15 in minute = every 15 min)
1-5 range (1-5 in weekday = Mon through Fri)
1,15 specific values (1st and 15th of month)

Practical Commands

Bash
## Edit personal crontab
crontab -e
## List current crontab
crontab -l
## Common crontab examples:
## Run backup daily at 1 AM
0 1 * * * /opt/scripts/backup.sh >> /var/log/backup.log 2>&1
## Health check every 5 minutes
*/5 * * * * /opt/scripts/health-check.sh
## Log cleanup every Sunday at 3 AM
0 3 * * 0 find /var/log/app -name '*.log' -mtime +30 -delete
## First day of month at midnight
0 0 1 * * /opt/scripts/monthly-report.sh
## Weekdays at 9 AM
0 9 * * 1-5 /opt/scripts/morning-check.sh
## System-wide cron jobs
ls /etc/cron.d/ ## arbitrary schedules
ls /etc/cron.daily/ ## runs daily
ls /etc/cron.hourly/ ## runs hourly
## Special shortcuts
@reboot /opt/scripts/startup.sh ## run once at boot
@daily /opt/scripts/daily.sh ## equivalent to 0 0 * * *
@hourly /opt/scripts/hourly.sh ## equivalent to 0 * * * *
## Debug PATH issues
## Add temporarily to see cron environment:
* * * * * env > /tmp/cron-env.txt
## Then: cat /tmp/cron-env.txt | grep PATH
## PATH=/usr/bin:/bin <- much less than your interactive PATH
## Verify cron is running
systemctl status cron ## Debian/Ubuntu
systemctl status crond ## RHEL

Troubleshooting

Symptom Command What to Check
Job not running systemctl status cron cron daemon running?
Job runs manually but not in cron Check PATH in script Use absolute paths
No output or errors Add >> /tmp/job.log 2>&1 Redirect output to file
Job runs twice Check /etc/cron.d/ too Duplicate entries in different files
Common Mistake

Using relative paths or commands not in cron's PATH. cron runs with a minimal PATH (/usr/bin:/bin). Commands in /usr/local/bin, /snap/bin, or other directories will not be found. Always use absolute paths like /usr/local/bin/node instead of just node.

Remember

crontab -r removes ALL cron jobs with no confirmation and no undo. It is one typo away from crontab -e. If you accidentally run it, immediately check if you have a backup and restore with crontab backup-file. Consider aliasing crontab to crontab -i in your shell config to always prompt before removing.

Frequently Asked Questions

Why do cron jobs that work fine when run manually sometimes fail silently when scheduled?

cron executes jobs with a minimal environment — no login shell, a stripped-down PATH, and none of the environment variables your interactive shell sources from .bashrc or .profile. A script that relies on `python` being on PATH, or an env var set in your shell profile, can fail under cron even though it runs perfectly when you type it yourself. This is the single most common cause of 'it works when I run it, but not on schedule.'

What's the standard fix for cron jobs failing silently, and what should always be logged?

Always redirect both stdout and stderr to a log file (`* * * * * /path/script.sh >> /var/log/script.log 2>&1`) — by default cron mails output to the user, which often goes nowhere on modern systems with no local MTA configured, so failures vanish entirely. Also set an explicit PATH at the top of the crontab and use absolute paths for every binary and file referenced inside the script, rather than relying on whatever PATH cron happens to provide.