How to Automate Tasks on a Server with Cron: A Practical Guide
Cron is the workhorse of Linux automation — it runs a command on a schedule, forever, with no supervision. It's how I schedule build jobs, backups, and content refreshes. Here's how to use it well.
1What cron does
Cron reads a "crontab" — a table of lines, each saying when to run and what to run. The system checks every minute and fires anything due.
2The crontab syntax
Edit your user's schedule with:
crontab -e
Each line is five time fields then the command:
* * * * * /path/to/command
│ │ │ │ │
│ │ │ │ └─ day of week (0-6, 0=Sunday)
│ │ │ └─── month (1-12)
│ │ └───── day of month (1-31)
│ └─────── hour (0-23)
└───────── minute (0-59)
* means "every." So:
0 3 * * *— 3:00 AM daily* * * * *— every minute30 9 * * 1— 9:30 AM Mondays0 0 1 * *— midnight on the 1st of each month
3Start with a log
Before you trust a job, make it visible. A common beginner mistake is a silent failure. Always log:
# every hour, append output to a log file
15 * * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
The >> appends; 2>&1 sends errors to the same log so you see both.
4Realistic examples
Daily backup script with a timestamped log:
30 2 * * * /root/scripts/backup.sh >> /var/log/backup.log 2>&1
Rebuild a static site every morning:
0 8 * * * /root/sites/mysite/build.sh >> /var/log/build.log 2>&1
Weekly cleanup:
0 4 * * 0 /usr/local/bin/clean-tmp.sh >> /var/log/cleanup.log 2>&1
5Cron PATH is minimal
This is the #1 cron gotcha: cron runs with a bare environment — often /usr/bin only, no ~/.bashrc, no your-PATH, no your environment variables. A command that works in your shell may fail under cron.
Fix it by using absolute paths to everything inside the job:
30 2 * * * /usr/bin/python3 /root/scripts/backup.py >> /var/log/backup.log 2>&1
And if a job needs your shell environment, wrap it and source your profile at the top:
30 2 * * * bash -lc '/root/scripts/backup.sh' >> /var/log/backup.log 2>&1
(bash -lc loads your login-shell environment.)
6Check your work
After saving, confirm the schedule and watch it run:
crontab -l # list your jobs
crontab -l | grep backup # confirm one is there
tail -f /var/log/backup.log # watch the log live
If a job isn't firing, the log tells you whether it ran and errored, or never ran at all.
7Pitfalls to avoid
- Silent failures — always
>> log 2>&1, or you'll discover a missing job weeks later. - Relative paths — a bare
backup.shor./scriptwon't resolve under cron; use full paths. - Wrong timezone — cron uses the system timezone; check with
datefirst. - Overlapping runs — if a job runs longer than its interval, two instances can collide; add a lock or
flockif it matters. - No newline at end — a crontab must end with a newline or some editors reject it.
Cron's power is that it just keeps running. Get the scheduling right, log everything, and you've automated the boring work for good.