Scheduling with cron ⏰
Good admins are lazy in the best way: anything that has to happen regularly (backups, cleanups, reports) gets handed to cron, a service that runs your commands on a schedule. It has been doing this job on Unix since the 1970s.
You will learn
- How to read and write the five time fields (
*/5 * * * *) - Your personal schedule:
crontab -e,-land-r - System schedules:
/etc/crontab,/etc/cron.d/and thecron.dailyfolders - How cron differs between Rocky and Ubuntu
- The classic traps that make cron jobs “silently not work”
Two families, one idea
| Rocky / RHEL | Ubuntu / Debian | |
|---|---|---|
| Package | cronie | cron |
| Service name | crond | cron |
| The tool you type | crontab on both | |
| Where user crontabs are stored | /var/spool/cron/USER | /var/spool/cron/crontabs/USER |
crontab -e opens in… | vi (unless you set EDITOR) | asks you the first time: nano is option 1 |
| Cron's log | /var/log/cron | /var/log/syslog (lines with CRON) |
| daily / weekly / monthly jobs run by | anacron (/etc/anacrontab): catches up if the machine was off | lines in /etc/crontab (anacron too, if installed) |
Heads up: the service is cron/crond, but the command you type is crontab. Typing cron -e won't work.
The five time fields
Every cron line is five time fields followed by the command. Read the fields left to right:
That line means “at 02:30, Monday to Friday.” Day of week: 0 or 7 = Sunday, 1 = Monday … 6 = Saturday.
| Symbol | Means | Example |
|---|---|---|
* | every value | * * * * * = every minute |
*/N | every N | */15 * * * * = every 15 minutes |
A-B | a range | 0 9-17 * * * = on the hour, 9am to 5pm |
A,B | a list | 0 8,20 * * * = 8:00 and 20:00 |
@daily @hourly @weekly @reboot | shortcuts | @reboot = once, whenever the computer starts |
In the practice terminal, type explain "0 2 * * 1-5" and it translates the schedule into plain English. On the web, crontab.guru does the same.
Your own schedule: crontab
crontab -e # edit your schedule (opens an editor) crontab -l # list it crontab -l > my-crontab.bak # back it up! crontab -r # REMOVE it, instantly, no "are you sure?" sudo crontab -u alex -l # root can see anyone's
-r is next to -eOn a keyboard, R sits right next to E. One typo and your whole crontab is gone. Plenty of admins have lost a year of carefully tuned jobs this way. Keep a backup with crontab -l > file.
Never edit the files in /var/spool/cron directly. Always go through crontab -e. It checks your syntax before installing, and it tells cron to reload. If you make a typo, it says something like bad minute and asks if you want to fix it.
crontab -e # opens vi: press i, type, Esc, :wq sudo dnf install nano EDITOR=nano crontab -e # or use nano this once
crontab -e # first time: pick 1 for nano select-editor # change your mind later
System-wide schedules
Jobs for the whole system live in /etc, and only root can edit them. There are three flavors:
1. /etc/crontab and 2. /etc/cron.d/
Same format as your crontab, but with one extra field: which user runs the job:
*/10 * * * * root /usr/local/bin/check-disk.sh time fields USER command
Instead of editing /etc/crontab itself, it's cleaner to drop a small file into /etc/cron.d/. Each app or task gets its own file, and you can remove it later without touching anything else:
echo '*/10 * * * * root date >> /var/log/heartbeat.log' | sudo tee /etc/cron.d/heartbeat
Debian's cron ignores files in /etc/cron.d/ whose names contain a dot. backup.cron or backup.sh will silently never run, while backup works. Rocky doesn't mind the dot. On both, the file must be owned by root and not writable by group or others, or cron ignores it (and logs a warning).
3. The drop-in folders
Don't care about the exact minute? Put an executable script into one of these folders and it runs roughly that often:
/etc/cron.hourly/ /etc/cron.daily/ /etc/cron.weekly/ /etc/cron.monthly/
The script needs chmod +x. On Ubuntu its name also can't contain a dot (the same run-parts rule). Look around: Ubuntu keeps things like logrotate and man-db in cron.daily. On Rocky, anacron runs these folders, so a daily job still happens after the laptop was switched off overnight.
Why isn't my cron job running?! 🐛
The same traps get everyone. Check this list first:
- Test the command by hand first. If it doesn't work in your terminal, it won't work in cron.
- Use full paths. Cron runs with a tiny
PATHand starts in your home folder. Write/home/student/backup.sh, notbackup.sh.which tartells you where a program lives. - Where did the output go? Cron tries to email it. Most servers have no mail set up, so it quietly disappears. Send it to a file instead:
… >> /home/student/job.log 2>&1(2>&1includes the error messages too, see lesson 11). - The
%trap. In a crontab,%means “new line.”date +%Fbreaks, so writedate +\%F, or better, put the command in a script. - The /bin/sh trap (Ubuntu). Cron runs jobs with
/bin/sh, which is dash on Ubuntu but bash on Rocky. Bash-only tricks like<( )or[[ ]]fail on Ubuntu withSyntax error. PutSHELL=/bin/bashon the first line of your crontab (lesson 12). - File names in cron.d / cron.daily: no dots on Ubuntu, and they need the right owner and permissions.
- Is cron even running?
systemctl status crond(Rocky) orsystemctl status cron(Ubuntu). - Check cron's log.
sudo cat /var/log/cronon Rocky,grep CRON /var/log/syslogon Ubuntu. If there's noCMDline, cron never tried to run it.
The modern alternative is systemd timers (systemctl list-timers). Both families use them for built-in chores like package-list refreshes. Cron is simpler to learn, and you'll find it on every Linux server.
Try it
The practice terminal runs a real cron clock. Jobs fire every minute, and a small ⏱ note appears in the title bar when they do. Don't want to wait? The playground-only timewarp 10m command jumps the clock forward and runs every job that would have been due.
Quick check
1. What does 0 */6 * * * mean?
✓ The first field is the minute (0), the second is the hour (every 6th).
2. What's different about a line in /etc/cron.d/ compared with crontab -e?
✓ System crontabs (/etc/crontab and /etc/cron.d/*) say WHO runs the job. Personal crontabs don't need to, since they're yours.
3. On Ubuntu you created /etc/cron.d/backup.job, but it never runs. Why?
✓ One of the sneakiest cron traps. Rocky wouldn't care about the dot.
4. What's the service called on Rocky?
✓ systemctl status crond on Rocky, systemctl status cron on Ubuntu.