How to Schedule Tasks on Linux with Cron (Run a Script Every Night)

Run a script every night with cron: Five fields and a command.

Backups at 2 am, a cleanup every Sunday, a check every five minutes — anything you'd otherwise have to remember to do can be handed to cron, the scheduler that's been in Linux since the beginning. One line per job in a file called the crontab.

Quick reference

TaskCommand
Edit your jobscrontab -e
List your jobscrontab -l
Edit root's jobssudo crontab -e
See what's runjournalctl -u cron -n 30
Test a schedulecrontab.guru

1. The five fields

Every line is a schedule followed by a command:

┌─ minute (0–59)
│ ┌─ hour (0–23)
│ │ ┌─ day of month (1–31)
│ │ │ ┌─ month (1–12)
│ │ │ │ ┌─ day of week (0–6, Sunday = 0)
│ │ │ │ │
* * * * * command

ScheduleMeaning
0 2 * * *2:00 am every day
*/5 * * * *every 5 minutes
30 7 * * 1-57:30 am Monday to Friday
0 3 * * 03:00 am every Sunday
0 0 1 * *midnight on the 1st of each month
@rebootonce, when the server starts

Paste any of these into crontab.guru and it explains it in words.

2. Add a job

crontab -e

The first time it asks which editor to use — pick nano. Add a line at the bottom:

0 2 * * * /home/john/backup.sh >> /home/john/backup.log 2>&1

Save and exit. Cron picks it up immediately — no restart needed.

The >> file 2>&1 part saves everything the script prints (and any errors) to a log file. Without it, output goes nowhere useful.

3. Check it ran

cat /home/john/backup.log
journalctl -u cron -n 30

The journal shows every job cron started and when.

4. Jobs that need root

sudo crontab -e

Root's crontab is separate from yours. Use it for system jobs like cleaning Docker or renewing certificates:

0 4 * * 0 docker system prune -af >> /var/log/docker-prune.log 2>&1

5. The three rules of cron

  1. Use full paths. Cron doesn't know where python or docker is. Write /usr/bin/python3, not python3. Find a path with which python3.
  2. Make scripts executable. chmod +x backup.sh.
  3. Capture output. Always add >> logfile 2>&1 so you can see what happened.

Easier alternative for simple cases

Drop a script into /etc/cron.daily/, /etc/cron.weekly/ or /etc/cron.hourly/ (as root, executable, no file extension) and it runs at that interval. No schedule syntax at all.

Troubleshooting

It works when I run it by hand but not from cron. Almost always rule 1: a command without a full path, or a script that relies on being in a certain folder (add cd /home/john && before it).

It runs at the wrong time. Cron uses the server's time zone. timedatectl to check; tutorial 9 to change it.

The log file is empty. The script printed nothing, which may be fine. Add echo "done $(date)" to the end of the script to prove it ran.

"No crontab for john". You haven't created one yet. crontab -e makes it.

Percent signs in the command. % has a special meaning in crontab. Escape as \% — this bites people using date +%Y.

Wrapping up

Five fields, one line, crontab -e. Full paths, executable scripts, output to a log file. Check crontab.guru when you're unsure of a schedule, and journalctl -u cron when you're unsure it ran.

Call us