Skip to content
Intermediate LinuxLesson 17 of 27 4 min read

Job Scheduling

Run commands automatically with cron, at, and their modern systemd-timer replacement.

On this page7 sections

So far, every command you've run happened because you typed it. Production systems also need work that happens without anyone typing anything - a nightly backup, an hourly cleanup, a report generated every Monday morning. Linux has had a tool for exactly that since the 1970s: cron.

crontab: the classic scheduler

Every user can have their own crontab (cron table) - a small file of scheduled jobs, managed with the crontab command:

bash
crontab -e     # edit your crontab in your default editor
crontab -l     # list your current scheduled jobs
crontab -r     # remove your entire crontab

Each line in a crontab has six fields: five that describe when, and one that says what:

minute hour day-of-month month day-of-week   command
30     2    *             *     *             /usr/local/bin/backup.sh

A * means "every value" for that field. The line above reads: run backup.sh at 02:30, every day of the month, every month, every day of the week - in other words, every night at 2:30 AM.

Reading cron syntax

FieldAllowed valuesExample
minute0-590 = on the hour
hour0-232 = 2 AM
day of month1-311 = the 1st
month1-126 = June
day of week0-6 (0 = Sunday)1 = Monday

A few more real examples:

0 * * * *      /usr/local/bin/hourly-check.sh     # every hour, on the hour
0 9 * * 1      /usr/local/bin/monday-report.sh    # 9 AM every Monday
*/15 * * * *   /usr/local/bin/poll.sh             # every 15 minutes
0 0 1 * *      /usr/local/bin/monthly-invoice.sh  # midnight on the 1st of every month

*/15 means "every 15 units," a shorthand you'll see constantly in real crontabs.

Shortcuts

Most cron implementations also accept these special strings in place of the five fields:

@reboot    run once, when the system boots
@daily     same as 0 0 * * *
@hourly    same as 0 * * * *
@weekly    same as 0 0 * * 0

at: run something once

When you need a job to run one time, not on a recurring schedule, at is the simpler tool:

bash
echo "/usr/local/bin/deploy.sh" | at 23:00     # run once, tonight at 11 PM
atq                                             # list pending at jobs

The modern alternative: systemd timers

On systems that already use systemd (which you met in the previous lesson), a systemd timer unit can do everything cron does, with two real advantages: it logs to journalctl like every other service, and it can easily "catch up" a missed run after the machine was off (Persistent=true). A timer unit pairs with a matching .service unit:

ini
# backup.timer
[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true

[Install]
WantedBy=timers.target

Which one you reach for is mostly a matter of what the system already uses: cron is simpler and universal across every Unix-like system; systemd timers integrate better if everything else on the box is already a systemd service.

The practice terminal simulates crontab and at well enough to practice the real commands below - just keep in mind nothing is actually scheduled in the background afterward, since a browser tab has no daemon sitting behind it the way a real system does.

Try it

Run these in the practice terminal (opens in a new tab). It opens in a new tab, so you keep your place here.
bash
echo '30 2 * * * /usr/local/bin/backup.sh' > mycron
crontab mycron
crontab -l
echo "/usr/local/bin/deploy.sh" | at 23:00
atq

crontab mycron installs that file as your schedule, and crontab -l reads it straight back - the same round trip you'd do on a real system.

Further reading

  • "The Linux Command Line" by William Shotts (No Starch Press) - covers cron, at, and anacron (cron's laptop-friendly cousin) together.
  • "How Linux Works" by Brian Ward (No Starch Press) - explains systemd timers as a direct comparison to cron, including the Persistent= behavior above.

Challenge

Write a crontab line into a file called mycron that runs /usr/local/bin/backup.sh every day at 2:30 AM, using a single redirected echo.

Want to experiment first? Try things in the practice terminal (opens in a new tab), then enter the command that solves the task here.

Quiz

Lock in the concepts. Score at least 80% to mark the lesson complete.

0 of 3 answered

Done with this one?

Skipped the challenge? You can mark the lesson complete by hand.

Your notes

Kept on this browser only.