Lab 08: Cron Jobs & Task Scheduling

Time: 30 minutes | Level: Practitioner | Docker: docker run -it --rm ubuntu:22.04 bash


Overview

Cron is Linux's built-in task scheduler — the engine behind automated backups, log rotation, report generation, and system maintenance. In this lab you'll master cron syntax, manage crontabs, use system-wide cron directories, handle environment variables, and capture cron output properly.


Step 1: Understanding Cron Syntax

Every cron job is a line with 5 time fields plus a command:

┌───────────── minute (0–59)
│ ┌───────────── hour (0–23)
│ │ ┌───────────── day of month (1–31)
│ │ │ ┌───────────── month (1–12)
│ │ │ │ ┌───────────── day of week (0–7, 0 and 7 = Sunday)
│ │ │ │ │
* * * * * command_to_run
# Demonstrate cron syntax interpretation
echo "Cron syntax examples:"
echo "30 8 * * 1-5     = 8:30 AM, Monday through Friday"
echo "0 */6 * * *      = every 6 hours (midnight, 6am, noon, 6pm)"
echo "*/15 * * * *     = every 15 minutes"
echo "0 0 1 * *        = midnight on the 1st of every month"
echo "0 2 * * 0        = 2:00 AM every Sunday"
echo "15 10 * * 1,3,5  = 10:15 AM on Mon, Wed, Fri"
echo "0 0 15 1,6,12 *  = midnight on Jan 15, Jun 15, Dec 15"

📸 Verified Output:

💡 Special characters: * = any value, , = list (1,3,5), - = range (1-5), / = step (*/15 means every 15). Remember: cron uses 0-indexed weekdays where both 0 AND 7 mean Sunday.


Step 2: User Crontabs with crontab

Each user has their own crontab file managed by the crontab command.

📸 Verified Output:

💡 Edit safely: Use crontab -e interactively (opens your $EDITOR). It validates syntax before saving. Never edit /var/spool/cron/crontabs/username directly — you'll bypass validation and may corrupt the file.


Step 3: @ Shortcuts — Human-Friendly Scheduling

📸 Verified Output:

💡 @reboot gotcha: Tasks run at boot run as the crontab owner, but the environment may differ from a login shell. Always use full paths (/usr/bin/python3, not python3) and set PATH explicitly in the crontab or script.


Step 4: System-Wide Cron with /etc/cron.d/

System cron files (managed by packages or admins) live in /etc/cron.d/. These have an extra user field.

📸 Verified Output:

💡 cron.d vs crontab: Files in /etc/cron.d/ must include the user field and are owned by packages/admins. User crontabs (via crontab -e) don't have a user field — they always run as the crontab owner. Prefer /etc/cron.d/ for system-level automation.


Step 5: Cron Environment Variables

Cron runs with a minimal environment — not your login shell's. Set variables explicitly.

📸 Verified Output:

💡 MAILTO variable: Set MAILTO="" to suppress emails for successful jobs. Set [email protected] to receive output by email. Any cron job that produces stdout/stderr output will trigger an email to MAILTO by default.


Step 6: Logging Cron Output

Proper logging is critical for cron job debugging.

📸 Verified Output:

💡 Always use >> log 2>&1: The >> appends (vs > overwrites), and 2>&1 captures stderr with stdout. Without 2>&1, errors silently disappear (or go to MAILTO). Add a timestamp to every log line: echo "[$(date '+%Y-%m-%d %H:%M:%S')] message".


Step 7: crontab -r and Safety Practices

📸 Verified Output:

💡 crontab -r is destructive: There's no undo. Always backup: crontab -l > ~/crontab.bak before editing or removing. Some systems offer crontab -i (interactive) which asks for confirmation before removal — check if your system supports it.


Step 8: Capstone — Automated System Maintenance Schedule

Scenario: Design a complete automated maintenance crontab for a production web server.

📸 Verified Output:

💡 Online cron parser: Use crontab.guruarrow-up-right to visually validate and explain cron expressions before deploying. The site shows the next execution times and describes expressions in plain English — invaluable for complex schedules.


Summary

Command / Concept
Purpose
Example

crontab -e

Edit user's crontab

Opens in $EDITOR

crontab -l

List user's crontab

crontab -l > backup.txt

crontab -r

Remove user's crontab

⚠️ Backup first!

* * * * *

Cron time fields

30 8 * * 1-5 = 8:30 AM weekdays

@reboot

Run at system startup

@reboot /opt/myapp/start.sh

@daily

Run once a day (midnight)

@daily /usr/bin/backup.sh

@weekly

Run weekly (Sunday midnight)

@weekly /usr/bin/cleanup.sh

/etc/cron.d/

System-wide cron files

Needs USER field: * * * * * root cmd

2>&1

Capture stderr with stdout

cmd >> log.txt 2>&1

MAILTO=""

Suppress cron email

Set in crontab header

MAILTO=addr

Email cron output

Last updated