OLE study materials
OLE study resources

OLE: Shell Scripting and Task Automation with cron and systemd Timers

OLE · Work through your exam, one topic at a time.

All guide sections

Shell Scripting and Task Automation with cron and systemd Timers

This domain tests writing reliable non-interactive scripts and scheduling them correctly with cron, at, or systemd timers.

Script hygiene

  • Start with #!/bin/bash and set -euo pipefail: fail on error, on unset variables, and on pipeline failures.
  • Quote expansions ("$var", "$@"), use [[ ]] for tests, case for branching, read -r for input, mktemp for temporary files, and trap for cleanup.
  • Positional parameters: $# count, $1 first argument, $? last exit status. Use absolute paths; cron's PATH is minimal.
  • Log deliberately: append to a file with timestamps, or write to stdout so journald captures it for timer-driven services.

cron

  • Per-user: crontab -e, -l, -r, -u user. System-wide: /etc/crontab, /etc/cron.d/, and the run-parts directories /etc/cron.{hourly,daily,weekly,monthly}.
  • Fields are minute, hour, day-of-month, month, day-of-week, then the command. A literal % must be escaped as \%.
  • MAILTO= and SHELL= can be set at the top of a crontab; /etc/cron.allow restricts who may use cron.

systemd timers

  • A foo.timer unit triggers foo.service. Key settings: OnCalendar=, OnBootSec=, Persistent=true (run missed jobs after downtime), RandomizedDelaySec=, AccuracySec=.
  • systemctl enable --now foo.timer, systemctl list-timers --all, and systemd-analyze calendar "Mon..Fri 02:30:00" to validate expressions.
  • at handles one-off jobs: echo /usr/local/bin/job.sh | at now +5 min, then atq and atrm.

Worked example

Convert the cron line 30 2 * * 1-5 /usr/local/bin/backup.sh into a timer. Use OnCalendar=Mon..Fri 02:30:00 in backup.timer, with Persistent=true so a missed run executes after reboot, and a matching backup.service running ExecStart=/usr/local/bin/backup.sh. Enable the timer, not the service. Reasoning: systemd expresses weekday ranges with .., and enabling the timer is what schedules the service.

Traps

  • An unescaped % in a crontab (date +%F) truncates the command.
  • Scripts that work interactively fail under cron because of PATH, environment variables, and missing relative paths.
  • Persistent=true is required for catch-up runs; without it, missed timers are simply skipped.
  • A timer unit without its matching service unit does nothing.