Skip to main content

Lab 6.4 - Cron and Crontab

Lab Objectives​

By the end of this lab, you will be able to:

  • Understand the cron system
  • Create scheduled tasks with crontab
  • Manage user and system crontabs
  • Monitor cron task execution
  • Troubleshoot common issues
  • Use systemd timers (modern alternative)

Estimated Duration​

45-60 minutes

Prerequisites​

  • Ubuntu 24.04 installed and functional
  • User access with sudo
  • Open terminal
  • Basic command line knowledge

Exercise 1: Introduction to Cron​

Step 1: Check the Cron Service​

# Check that cron is installed and active
systemctl status cron

# If not installed (normally installed by default)
sudo apt update
sudo apt install cron

# Start and enable
sudo systemctl enable cron
sudo systemctl start cron

Step 2: Understand the Structure​

# View system crontabs
ls -la /etc/cron.*

# View user crontabs
ls -la /var/spool/cron/crontabs/

# View the current user's crontab
crontab -l

Exercise 2: User Crontab​

Step 1: Edit the Crontab​

# Edit the current user's crontab
crontab -e

# The first time, choose an editor (nano recommended)

Step 2: Crontab Syntax​

Format: minute hour day month day-of-week command

# Syntax examples:
# * * * * * = Every minute
# 0 * * * * = Every hour (minute 0)
# 0 0 * * * = Every day at midnight
# 0 0 * * 0 = Every Sunday at midnight
# */5 * * * * = Every 5 minutes

Step 3: Create a Simple Task​

# Create a test script
cat > ~/test-cron.sh << 'EOF'
#!/bin/bash
echo "Cron executed at $(date)" >> ~/cron-test.log
EOF

chmod +x ~/test-cron.sh

# Add to crontab (run every minute for testing)
crontab -e
# Add this line:
# * * * * * /home/$USER/test-cron.sh

# View the crontab
crontab -l

# Wait 2-3 minutes, then check
cat ~/cron-test.log

Exercise 3: Common Tasks​

Step 1: Daily Backup​

# Create a backup script
cat > ~/backup-daily.sh << 'EOF'
#!/bin/bash
BACKUP_DIR="$HOME/backups"
DATE=$(date +%Y%m%d)
mkdir -p "$BACKUP_DIR"
tar -czf "$BACKUP_DIR/backup-$DATE.tar.gz" ~/Documents 2>/dev/null
echo "Backup created: backup-$DATE.tar.gz"
EOF

chmod +x ~/backup-daily.sh

# Add to crontab (every day at 2 AM)
crontab -e
# Add:
# 0 2 * * * /home/$USER/backup-daily.sh >> /home/$USER/backup.log 2>&1

Step 2: Weekly Cleanup​

# Cleanup script
cat > ~/cleanup-weekly.sh << 'EOF'
#!/bin/bash
# Delete temporary files > 7 days
find ~/tmp -type f -mtime +7 -delete 2>/dev/null
# Clean old logs
find ~/logs -name "*.log" -mtime +30 -delete 2>/dev/null
echo "Cleanup done: $(date)"
EOF

chmod +x ~/cleanup-weekly.sh

# Add to crontab (every Sunday at 3 AM)
crontab -e
# Add:
# 0 3 * * 0 /home/$USER/cleanup-weekly.sh

Step 3: System Monitoring​

# Monitoring script
cat > ~/monitor-system.sh << 'EOF'
#!/bin/bash
LOG="$HOME/system-monitor.log"
{
echo "=== $(date) ==="
echo "CPU: $(top -bn1 | grep 'Cpu(s)' | awk '{print $2}')"
echo "Memory: $(free -h | grep Mem | awk '{print $3"/"$2}')"
echo "Disk: $(df -h / | tail -1 | awk '{print $5}')"
echo "---"
} >> "$LOG"
EOF

chmod +x ~/monitor-system.sh

# Run every 5 minutes
crontab -e
# Add:
# */5 * * * * /home/$USER/monitor-system.sh

Exercise 4: Environment Variables​

Step 1: Configure the Environment​

# The crontab does not have the same environment as your shell
# You need to define the necessary variables

crontab -e
# Add at the top of the file:
# PATH=/usr/bin:/bin
# SHELL=/bin/bash
# HOME=/home/$USER
# MAILTO=your-email@example.com

# Example with defined PATH
# */5 * * * * /usr/bin/curl http://example.com >> /tmp/curl.log 2>&1

Step 2: Absolute Paths​

# Always use absolute paths in cron
# ❌ Bad:
# * * * * * script.sh

# ✅ Good:
# * * * * * /home/$USER/script.sh

# Or define in the script:
# #!/bin/bash
# cd /home/$USER
# ./script.sh

Exercise 5: System Crontab​

Step 1: System Crontab​

# Edit the system crontab
sudo crontab -e

# Or create a file in /etc/cron.d/
sudo nano /etc/cron.d/my-task

# Format with user:
# * * * * * user /path/to/script.sh

# Example: system backup every day at 1 AM
# 0 1 * * * root /usr/local/bin/system-backup.sh

Step 2: System Cron Directories​

# /etc/cron.daily/ - Daily execution
ls -la /etc/cron.daily/

# /etc/cron.weekly/ - Weekly execution
ls -la /etc/cron.weekly/

# /etc/cron.monthly/ - Monthly execution
ls -la /etc/cron.monthly/

# /etc/cron.hourly/ - Hourly execution
ls -la /etc/cron.hourly/

# Create a script in cron.daily
sudo nano /etc/cron.daily/my-script
# Add:
#!/bin/bash
# Your script here

# Make executable
sudo chmod +x /etc/cron.daily/my-script

Exercise 6: Monitoring and Logs​

Step 1: View Cron Logs​

# Ubuntu 24.04 uses systemd, logs are in journalctl
sudo journalctl -u cron

# View the latest entries
sudo journalctl -u cron -n 50

# Follow in real-time
sudo journalctl -u cron -f

# Filter by user
sudo journalctl -u cron | grep $USER

# View today's executions
sudo journalctl -u cron --since today

Step 2: Verify Execution​

# Script to check if cron executed a task
cat > ~/check-cron.sh << 'EOF'
#!/bin/bash
SCRIPT="$HOME/test-cron.sh"
LOG="$HOME/cron-test.log"

# Check last execution
if [ -f "$LOG" ]; then
LAST_RUN=$(tail -1 "$LOG" | awk '{print $4, $5}')
echo "Last execution: $LAST_RUN"
else
echo "No execution found"
fi

# Check in system logs
echo "System logs:"
sudo journalctl -u cron | grep "$SCRIPT" | tail -5
EOF

chmod +x ~/check-cron.sh
./check-cron.sh

Exercise 7: Troubleshooting​

Step 1: Common Issues​

# Issue: Script does not run
# Solution 1: Check permissions
chmod +x ~/my-script.sh

# Solution 2: Check paths
which command-in-script

# Solution 3: Test manually
bash ~/my-script.sh

# Solution 4: Check logs
sudo journalctl -u cron | tail -20

Step 2: Debug​

# Add logging in the script
cat > ~/script-debug.sh << 'EOF'
#!/bin/bash
set -x # Debug mode
exec > /tmp/script-debug.log 2>&1
echo "Start: $(date)"
# Your code here
echo "End: $(date)"
EOF

# In crontab, also redirect
# * * * * * /home/$USER/script-debug.sh >> /tmp/cron-debug.log 2>&1

Exercise 8: systemd Timers (Modern Alternative)​

Step 1: Create a Timer​

# Create a service
cat > ~/.config/systemd/user/backup.service << 'EOF'
[Unit]
Description=Daily backup

[Service]
Type=oneshot
ExecStart=/home/$USER/backup-daily.sh
EOF

# Create a timer
cat > ~/.config/systemd/user/backup.timer << 'EOF'
[Unit]
Description=Timer for daily backup

[Timer]
OnCalendar=daily
OnCalendar=02:00
Persistent=true

[Install]
WantedBy=timers.target
EOF

# Reload and enable
systemctl --user daemon-reload
systemctl --user enable backup.timer
systemctl --user start backup.timer

# Verify
systemctl --user list-timers

Verification​

Checklist​

Verify that you can:

  • Edit a user crontab
  • Understand cron syntax
  • Create scheduled tasks
  • Configure environment variables
  • View cron logs
  • Troubleshoot common issues
  • Use systemd timers (optional)

Reflection Questions​

  1. Why use absolute paths in cron?

    • Cron does not have the same PATH as your shell
    • Relative paths may fail
  2. What is the difference between user and system crontab?

    • User: crontab -e (file in /var/spool/cron/)
    • System: /etc/crontab or /etc/cron.d/
  3. When to use systemd timers vs cron?

    • systemd timers: More modern, better integration
    • cron: Simpler, universally supported

Next Steps​

  • Chapter 8.3: Advanced Cron and systemd Timers
  • Module 11: Monitoring Crons and Alerts
  • Module 12: Complete Automation

Ubuntu 24.04 Resources​

  • man crontab - Crontab documentation
  • man 5 crontab - Crontab file format
  • systemctl --user list-timers - View systemd timers
  • Ubuntu Cron Guide

Lab created on: December 2024 - Tested on Ubuntu 24.04