cron
A crontab line has five time fields plus a command:
System cron lives in /etc/cron.d/, /etc/crontab, /etc/cron.{daily,weekly}.
Running tasks on a schedule: crontab syntax, classic cron and modern systemd timers.
crontab -e
edit your own crontab
crontab -l
show the current crontab
*/15 * * * * /usr/local/bin/backup.sh
every 15 minutes
systemctl list-timers
list systemd timers
journalctl -u backup.service
log for a specific job
grep CRON /var/log/syslog
what cron ran
Two systems run tasks on a schedule:
OnCalendar, persistent), integrated into systemd.For new jobs on servers, timers are often preferred; cron is for when you need something quick and familiar.
A crontab line has five time fields plus a command:
System cron lives in /etc/cron.d/, /etc/crontab, /etc/cron.{daily,weekly}.
Personal crontabs live in /var/spool/cron/crontabs/, one file per user.
The directory is closed: only root sees the list, and only the owner reads
a file.
Every cron run writes to the log: CRON[2086]: (deploy) CMD
(/usr/local/bin/tweak.sh) — that is how you find whose job ran.
Do not edit the file in /var/spool/cron/crontabs/ by hand: crontab
checks the syntax and gives the file the right mode and owner. After
crontab -r you get no crontab for deploy: every line is gone, not one.
cron reads the schedule in the machine's time zone:
0 3 * * * means 03:00 by the time date shows. The machine's zone is
in timedatectl (timedatectl); on the lab machine it is
Etc/UTC.
cron picks up a zone change without a restart. The job 19 21 * * *
fired at 21:19 Tokyo time after
sudo timedatectl set-timezone Asia/Tokyo:
A TZ=Asia/Tokyo line in a crontab changes only the job's environment:
date inside it prints Tokyo time, but the job still fires by the
machine's zone. A server is usually kept in UTC — then the schedule is
written in UTC. date shows what a time in another zone is in UTC:
03:00 in Moscow is 00:00 UTC: the schedule line is 0 0 * * *.
A pair of files: .service (what to do) + .timer (when).
The OnCalendar schedule, the service environment and timer troubleshooting
are covered in systemd-timers.
$PATH and no interactive-session environment
(aliases, variables from ~/.bashrc) — use absolute paths to commands and
files, do not rely on what an ordinary terminal shows.journalctl -u cron (Ubuntu 24.04) or grep CRON /var/log/syslog
(if cron logs to syslog rather than only to journald).% character in a command means a
newline to cron, so it needs escaping (\%).Add Persistent=true — it runs the missed job after the machine comes back up.
systemctl list-timers --all shows every timer, including inactive ones, with
the last and next run times.
crontab -e edits the current user's crontab (stored under
/var/spool/cron/crontabs/) — separate from the system files /etc/crontab
and /etc/cron.d/*, where an extra field names the user to run the command
as. Mixing up the formats is a common reason a job "works for me in
crontab -e" but not as a system job.
Found an inaccuracy? Report an error in the article