Cron Jobs on Linux: Schedule Tasks (with Examples)
Automate tasks with cron on Ubuntu 24.04: crontab syntax explained field by field, real examples, output logging, and when a systemd timer fits better.
Cron is the time-based job scheduler that has run background tasks on Unix systems for decades. If you need a script to run every night, a backup to fire every hour, or a cleanup to happen every Monday morning, cron is the classic, dependable tool to do it. On Ubuntu 24.04 LTS the cron daemon is installed and enabled by default, so you can start scheduling jobs immediately.
This tutorial explains the crontab syntax field by field, shows real-world examples, demonstrates how to capture output and logs so your jobs do not fail silently, and explains when a systemd timer is the better choice. Every command targets Ubuntu 24.04.
Prerequisites
- Ubuntu 24.04 LTS with a user account that can run the tasks you want to schedule.
sudoaccess only if you need to edit another userโs crontab or a system-wide schedule.
Confirm the cron service is running:
systemctl status cronYou should see active (running). If it is not enabled, turn it on with sudo systemctl enable --now cron.
Understanding crontab syntax
Each line in a crontab describes one scheduled job with five time fields followed by the command to run:
# โโโโโโโโโโ minute (0 - 59)
# โ โโโโโโโโ hour (0 - 23)
# โ โ โโโโโโ day of month (1 - 31)
# โ โ โ โโโโ month (1 - 12)
# โ โ โ โ โโ day of week (0 - 7, Sunday = 0 or 7)
# โ โ โ โ โ
# * * * * * command-to-runAn asterisk * means โevery value.โ You can also use lists (1,15,30), ranges (1-5), and steps (*/10 meaning every tenth unit).
Step 1: Edit your crontab
Open your personal crontab in the default editor:
crontab -eThe first time, Ubuntu asks which editor to use; pick nano if unsure. Add jobs one per line, save, and exit. List your current jobs at any time:
crontab -lStep 2: Real-world scheduling examples
Here are common patterns you can paste directly into your crontab:
# Run a backup script every day at 02:30 30 2 * * * /home/alice/scripts/backup.shRun a sync every 15 minutes
*/15 * * * * /usr/local/bin/sync-data.sh
Clean a temp directory every Monday at 04:00
0 4 * * 1 /usr/bin/find /tmp/cache -type f -mtime +7 -delete
Run a job on the first of every month at midnight
0 0 1 * * /home/alice/scripts/monthly-report.sh
Cron also supports convenient shortcuts in place of the five fields:
@reboot /home/alice/scripts/startup.sh
@daily /home/alice/scripts/cleanup.sh
@hourly /usr/local/bin/poll.shStep 3: Capture output and logging
By default, anything a cron job prints to stdout or stderr is mailed to the local user โ which usually means it vanishes if no mail system is configured. Always redirect output to a log file so you can diagnose failures:
30 2 * * * /home/alice/scripts/backup.sh >> /var/log/backup.log 2>&1Here >> appends stdout to the log and 2>&1 redirects stderr into the same place. To watch cron itself decide what to run, inspect the system journal:
journalctl -u cron --since '1 hour ago'Step 4: Mind the cron environment and PATH
Cron runs jobs with a minimal environment, not your interactive shell. The most common cause of โworks in my terminal but fails in cronโ is a short PATH. Either use absolute paths to every binary, or set the environment at the top of the crontab:
SHELL=/bin/bash PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin MAILTO=alice@example.com
0 6 * * * backup-tool --full
Step 5: System-wide and packaged cron jobs
Beyond per-user crontabs, Ubuntu offers system locations for scheduled jobs. Drop-in scripts placed in these directories run automatically:
/etc/cron.hourly/
/etc/cron.daily/
/etc/cron.weekly/
/etc/cron.monthly/For finer control with a user column, edit /etc/crontab or add a file under /etc/cron.d/. These system crontabs add a sixth field โ the user to run as:
# m h dom mon dow user command
0 3 * * * root /usr/local/bin/rotate-logs.shVerification: prove a job runs
Do not wait until 2 a.m. to find out a job is broken. Temporarily schedule it for the next minute and watch the log:
* * * * * /home/alice/scripts/backup.sh >> /tmp/cron-test.log 2>&1Then tail the output:
tail -f /tmp/cron-test.logOnce you confirm it runs and logs as expected, change the schedule back to its real time.
Cron vs. systemd timers
Cron is perfect for simple, periodic jobs. A systemd timer is the better choice when you need: dependency ordering against other services, accurate handling of missed runs after downtime (Persistent=true), resource limits, or unified logging in the journal. As a rule of thumb, reach for cron for quick periodic scripts and a systemd timer when the job is really a managed service. Our guide to managing systemd services with systemctl covers building units and timers.
Troubleshooting and common pitfalls
- Job never runs โ check the schedule fields and confirm cron is active with
systemctl status cron. - Works manually, fails in cron โ almost always a
PATHor environment issue; use absolute paths. - Percent signs eaten โ in crontab, an unescaped
%becomes a newline. Escape it as%or wrap the command in a script. - No output anywhere โ you forgot to redirect; add
>> logfile 2>&1.
Conclusion
You now understand crontab syntax, can schedule real jobs, capture their output, avoid the classic PATH trap, and know when a systemd timer fits better. Reliable scheduling underpins backups, maintenance, and automation on every server. When you scale this kind of automation across a fleet, clouditiv operates the orchestration for you on a sovereign, ISOย 27001 / BSIย C5 private cloud running Ubuntu 24.04 + OpenStack 2025.2 โ see how we handle automated provisioning, or take it further with the OpenStack CLI for cloud-native automation.