Read

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.

LineRuns
*/5 * * * * cmdEvery five minutes
0 * * * * cmdAt the start of every hour
30 2 * * * cmdEvery day at 02:30
0 9 * * 1-5 cmdWeekdays at 09:00
0 0 1 * * cmdMidnight 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

CommandWhat it does
crontab -lList your crontab.
crontab -eEdit it in vi.
echo 'LINE' | crontab -Install a one-line table (replaces!).
(crontab -l; echo 'LINE') | crontab -Append a line, keeping the rest.
crontab -rRemove the whole table.
crond -bStart the cron daemon in the background.
pidof crondIs the daemon running?

Quiz

  1. 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
  2. How do you write "every 10 minutes"?

    • `10 * * * *`
    • `*/10 * * * *`
    • `* 10 * * *`
  3. 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.
  4. 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
  5. What does `crontab -r` do?

    • Reloads the table
    • Removes your whole crontab without asking
    • Runs every job right now

Practice

  1. 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.)

  2. 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.

  3. 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.