Bash Tutorial · Linux System Skills · Lesson 28 of 30

Bash Scheduling with cron and systemd Timers

Run scripts on a schedule with cron and systemd timers, and write scripts that behave well when scheduled.

Create a free account to save this page, take notes and track your progress. Sign in

cron

crontab -e edits your scheduled jobs. Each line is minute hour day-of-month month day-of-week command:

# every day at 03:30, append output to a log
30 3 * * * /opt/scripts/backup.sh >> /var/log/backup.log 2>&1
# every 15 minutes on weekdays
*/15 * * * 1-5 /opt/scripts/sync.sh

cron runs with a minimal environment (short PATH, no profile), so use absolute paths and set what you need inside the script.

systemd timers

On modern Linux servers, systemd timers add logging (journalctl -u backup), dependencies and catch-up for missed runs:

# /etc/systemd/system/backup.timer
[Timer]
OnCalendar=*-*-* 03:30:00
Persistent=true
[Install]
WantedBy=timers.target

Scheduled-script checklist

Use strict mode, absolute paths, a lock so runs don't overlap (flock), and log with timestamps:

A cron-friendly script with a lock
cat > nightly.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
exec 9>"$HOME/nightly.lock"
flock -n 9 || { echo "already running, skipping"; exit 0; }
log() { printf '%s %s\n' "$(date -u -d @1768471200 +%FT%TZ)" "$*"; }
log "backup started"
log "backup finished"
EOF
chmod +x nightly.sh
./nightly.sh
flock "$HOME/nightly.lock" sleep 1 &      # another run holds the lock
sleep 0.2
./nightly.sh
wait

Output

2026-01-15T10:00:00Z backup started
2026-01-15T10:00:00Z backup finished
already running, skipping

Run this on your computer — see “Get Started” for setup.

Test yourself

Why do cron jobs often fail when the same script works in your terminal?

  1. cron can't run bash
  2. cron runs with a minimal environment and a short PATH
  3. cron needs root
  4. cron ignores the shebang
Show answer

Answer: cron runs with a minimal environment and a short PATH

Was this page helpful?