Module 10 · Putting it all together
Scheduling with crontab
Run commands automatically at fixed times: the five time fields, installing and listing a crontab, and starting the crond daemon that executes it.
What you will learn
- Read and write the five time fields of a crontab line.
- Install, list, extend and remove a crontab with `crontab`.
- Write jobs that work unattended: absolute paths and redirected output.
Backups at 2 a.m., log clean-ups every Sunday, a health check every five minutes: these are jobs for cron. The daemon crond wakes up once a minute, reads each user's crontab (cron table) and runs every line whose time matches. You never edit the table files directly; the crontab command installs, lists and removes them for you.
The five time fields
# ┌──────── minute (0-59)
# │ ┌───── hour (0-23)
# │ │ ┌─── day of month (1-31)
# │ │ │ ┌─ month (1-12)
# │ │ │ │ ┌ day of week (0-6, 0 = Sunday)
# │ │ │ │ │
30 2 * * * /root/bin/backup.sh
Each line has five time fields and then the command. * means "every". A field can also hold a list (1,15), a range (1-5) or a step (*/10, every ten). A line runs when all fields match the current time, so 30 2 * * * means "at 02:30 every day". Lines starting with # are comments.
| Line | Runs |
|---|---|
*/5 * * * * cmd | Every five minutes |
0 * * * * cmd | At the start of every hour |
30 2 * * * cmd | Every day at 02:30 |
0 9 * * 1-5 cmd | Weekdays at 09:00 |
0 0 1 * * cmd | Midnight on the first of each month |
Managing your crontab
In this VM there is one preparation step: the tables live in /var/spool/cron/crontabs, and that directory does not exist yet (crontab complains can't change directory). Create it once with mkdir -p. Then:
~% mkdir -p /var/spool/cron/crontabs
~% echo '30 2 * * * /root/bin/backup.sh' | crontab -
~% crontab -l
30 2 * * * /root/bin/backup.sh
~% (crontab -l; echo '*/15 * * * * /root/bin/check.sh >> /tmp/check.log 2>&1') | crontab -
~% crontab -l
30 2 * * * /root/bin/backup.sh
*/15 * * * * /root/bin/check.sh >> /tmp/check.log 2>&1
~% crontab -r
~% crontab -l
crontab: can't open 'root': No such file or directory
crontab FILE installs FILE as your whole table, and crontab - reads it from standard input. Both replace the existing table, which is why adding a line uses the subshell trick from lesson 96: list the current table, append the new line, and feed the result back. crontab -e opens the table in vi (lessons 28 and 29) and installs it when you save; crontab -l lists it; crontab -r removes it entirely, without asking. As root, -u USER manages another user's table.
The daemon, and jobs that work alone
A crontab does nothing unless crond is running. Check with pidof crond or ps | grep crond; start it with crond -b (background). For debugging, crond -f -l 0 stays in the foreground and logs everything it does. Remember that jobs run without you: no terminal, a minimal PATH, and the home directory as working directory. So use absolute paths for every command and file, and redirect output to a log (>> /tmp/job.log 2>&1) or it is simply lost.
Commands in this lesson
| Command | What it does |
|---|---|
crontab -l | List your crontab. |
crontab -e | Edit it in vi. |
echo 'LINE' | crontab - | Install a one-line table (replaces!). |
(crontab -l; echo 'LINE') | crontab - | Append a line, keeping the rest. |
crontab -r | Remove the whole table. |
crond -b | Start the cron daemon in the background. |
pidof crond | Is the daemon running? |
Quiz
What does `0 9 * * 1-5 /root/bin/report.sh` mean?
- Every day at 09:00
- Monday to Friday at 09:00
- From the 1st to the 5th of each month at 09:00
How do you write "every 10 minutes"?
- `10 * * * *`
- `*/10 * * * *`
- `* 10 * * *`
You run `echo '0 3 * * * /root/bin/b.sh' | crontab -`. What happens to the lines already in your crontab?
- They are kept; the new line is appended.
- They are replaced: the table now has only the new line.
- crontab refuses because a table exists.
Your job works when you run it by hand but not from cron. First suspect?
- Relative paths or commands not found in cron's minimal PATH
- Cron only runs scripts ending in .cron
- The job is too long
What does `crontab -r` do?
- Reloads the table
- Removes your whole crontab without asking
- Runs every job right now
Practice
Install a crontab for root with a single line that runs `/root/bin/backup.sh` every day at 02:30. (The directory `/var/spool/cron/crontabs` has been created for you.)
Root's crontab already runs the backup at 02:30. Add a second line that runs `/root/bin/check.sh` every 15 minutes, **keeping** the backup line.
A crontab does nothing without its daemon. Start `crond` in the background.
Open this lesson in the app to do the tasks in a real Linux machine and have them checked.