Command linemediumBash

Cron Job Scheduling

Create and manage scheduled tasks with cron and systemd timers.

01

The problem

You need to schedule regular tasks, automate backups, or run periodic maintenance.

02

The solution

Bash
# Edit crontab for current user
crontab -e

# List current cron jobs
crontab -l

# Remove all cron jobs
crontab -r

# View system crontab
sudo cat /etc/crontab
ls /etc/cron.*/

# Cron time format
# * * * * * command
# │ │ │ │ │
# │ │ │ │ └─ Day of week (0-6, 0=Sunday)
# │ │ │ └─── Month (1-12)
# │ │ └───── Day of month (1-31)
# │ └─────── Hour (0-23)
# └───────── Minute (0-59)

# Examples
* * * * * command              # Every minute
*/5 * * * * command            # Every 5 minutes
0 * * * * command              # Hourly
0 0 * * * command              # Daily at midnight
0 0 * * 0 command              # Weekly (Sunday)
0 0 1 * * command              # Monthly (1st day)
0 9-17 * * 1-5 command         # Weekdays 9AM-5PM
0 0,12 * * * command           # Midnight and noon
@reboot command                # At system boot
@daily command                 # Same as 0 0 * * *
@weekly command                # Same as 0 0 * * 0
@monthly command               # Same as 0 0 1 * *
@yearly command                # Same as 0 0 1 1 *

# Special variables in crontab
SHELL=/bin/bash
PATH=/usr/bin:/bin:/usr/local/bin
[email protected]
HOME=/home/user

# Redirect output
* * * * * command > /dev/null 2>&1           # Discard all output
* * * * * command >> /var/log/cron.log 2>&1  # Log to file

# Multiple commands
* * * * * command1 && command2
* * * * * command1; command2
* * * * * /path/to/script.sh

# Environment in crontab
* * * * * . $HOME/.profile; command

# Systemd timer (alternative to cron)
# Create /etc/systemd/system/mytimer.timer:
[Unit]
Description=Run mytask daily

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target

# Create /etc/systemd/system/mytimer.service:
[Unit]
Description=My Task

[Service]
Type=oneshot
ExecStart=/path/to/script.sh

# Enable and start
sudo systemctl enable mytimer.timer
sudo systemctl start mytimer.timer

# View active timers
systemctl list-timers

# Anacron (for systems that aren't always on)
# Edit /etc/anacrontab

# Quick one-time scheduling with 'at'
echo "command" | at 14:30 tomorrow
at -l                         # List jobs
at -c job_id                  # View job
at -d job_id                  # Delete job

03

Put it to work

Example
# Backup database daily at 2 AM
0 2 * * * /home/user/backup_db.sh >> /var/log/backup.log 2>&1

# Sync files every hour during business hours
0 9-17 * * 1-5 /usr/bin/rsync -av /data/ backup_server:/backup/

# Update package list weekly
0 0 * * 0 apt-get update && apt-get upgrade -y

# Clean temp files daily
@daily find /tmp -type f -atime +7 -delete

# Monitor disk space every 30 minutes
*/30 * * * * df -h > /var/log/disk_usage.log

# Systemd timer for weekly report
# /etc/systemd/system/weekly-report.timer:
[Timer]
OnCalendar=weekly
Unit=weekly-report.service

# /etc/systemd/system/weekly-report.service:
[Service]
Type=oneshot
ExecStart=/usr/local/bin/generate_report.sh

# Enable: sudo systemctl enable --now weekly-report.timer

# Schedule script with environment
[email protected]
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
0 3 * * * . /home/user/.bashrc; /home/user/nightly-job.sh

Worth knowing

Cron uses user's environment, set PATH explicitly. Use absolute paths. Redirect output to avoid mail spam. Test commands manually first. systemd timers offer more features than cron. Use flock to prevent overlapping jobs.