SkillByAIOpen interactive version →

Lesson 21 / 25

Scheduling with cron and systemd Timers

Schedule scripts reliably and account for their minimal environment.

Scripts that run without you

cron runs commands on a schedule defined by five fields: minute, hour, day of month, month and day of week, so 30 2 * * * means 02:30 every day. Edit your table with crontab -e; system jobs live in /etc/cron.d/. The classic cron surprise is its minimal environment: a short PATH, no shell profile, a different working directory and often sh rather than Bash, so use absolute paths, set PATH at the top of the crontab or script, cd explicitly and send output to a log, because by default cron mails output to the user, which often goes nowhere. On systemd-based Linux, systemd timers are a modern alternative: a .service unit describes the job and a .timer unit schedules it, with logs in the journal (journalctl -u backup.service), dependency handling, Persistent=true to catch up on runs missed while the machine was off, and randomised delays. In containers and Kubernetes, use a CronJob resource instead.

A crontab entry and the equivalent systemd timer

Absolute paths, explicit logging and a lock prevent the classic cron problems.

# crontab -e
PATH=/usr/local/bin:/usr/bin:/bin
MAILTO=""
30 2 * * * /usr/bin/flock -n /run/lock/backup.lock /opt/scripts/backup.sh >> /var/log/backup.log 2>&1

# /etc/systemd/system/backup.service
# [Service]
# Type=oneshot
# ExecStart=/opt/scripts/backup.sh
#
# /etc/systemd/system/backup.timer
# [Timer]
# OnCalendar=*-*-* 02:30:00
# Persistent=true
# RandomizedDelaySec=5m
# [Install]
# WantedBy=timers.target
#
# systemctl enable --now backup.timer ; journalctl -u backup.service

Test with the cron environment

A script that works in your terminal may fail under cron because of PATH or working-directory differences. Test with env -i PATH=/usr/bin:/bin /bin/bash /opt/scripts/backup.sh to simulate the minimal environment.

Quick check: Why do scripts often fail under cron even though they work in a terminal?

  • cron cannot run Bash at all
  • cron only allows one script per day
  • cron runs with a minimal environment: short PATH, no profile and a different working directory
  • cron removes execute permissions
Answer

cron runs with a minimal environment: short PATH, no profile and a different working directory — The stripped-down environment breaks scripts that rely on interactive settings.