Cron and Scheduled Tasks
You've reached the end
The final article of the series. You can write scripts (Article 16); now have them run on a schedule — nightly backups, weekly log cleanup, hourly data syncs — with cron. Then we wrap up the whole journey.
Environment note: like systemd (Article 15), cron is a background service that needs a daemon running. In an ordinary container the cron daemon doesn't run by default (install it with
apt install cron, you can manage the crontab, but jobs won't actually fire until thecronservice runs). For full hands-on practice, use a real VM/server.
What cron is
cron is a background service that reads the "schedules" you declare and runs commands at the right time. Each user's schedule lives in a table called the crontab.
crontab syntax: 5 time fields
Each crontab line has 5 time fields + a command:
* * * * * command-to-run
│ │ │ │ │
│ │ │ │ └── day of week (0-7; both 0 and 7 are Sunday)
│ │ │ └──── month (1-12)
│ │ └────── day of month (1-31)
│ └──────── hour (0-23)
└────────── minute (0-59)
* means "every value". A few examples to get used to reading:
*/5 * * * * every 5 minutes
0 * * * * at the top of every hour (minute 0)
0 2 * * * 2 AM every day
0 3 * * 0 3 AM every Sunday
30 0 1 * * 00:30 on the 1st of every month
*/N means "every N units". If it feels confusing, the website crontab.guru (a lookup tool, no install needed) helps you read/write schedules quickly.
Managing the crontab
crontab -e # open your crontab to edit (in an editor — Article 4)
crontab -l # list the current crontab
crontab -r # delete the entire crontab (careful!)
Example of a backup line running every 5 minutes, logging output:
*/5 * * * * /opt/backup.sh >> /var/log/backup.log 2>&1
Note the >> /var/log/backup.log 2>&1 part (recall Article 6): cron runs silently in the background, so you must redirect output and errors to a log file yourself — otherwise, when a job fails, you'll have no idea. This is an almost mandatory pattern for every cron job.
Cron's pitfalls (the biggest time-sinks)
cron runs jobs in a minimal environment, very different from your interactive shell. This is the source of most "works by hand, doesn't work in cron" bugs:
- Minimal PATH: cron doesn't have the full PATH your shell has. So always use absolute paths for commands and files in a cron-run script (
/usr/bin/nodeinstead ofnode,/opt/app/datainstead ofdata). - None of your environment variables: variables from
.bashrcaren't there. If a script needs them, declare them directly in the script or in the crontab. - A different working directory: cron runs from the user's home directory, not where you think. Use an explicit
cdor absolute paths. - Forgetting to log: add
>> file.log 2>&1so you can debug.
The golden rule: a cron-run script should use absolute paths for everything and log itself.
System crontabs and shortcuts
Beyond the user's crontab, the system also has the directories /etc/cron.daily/, /etc/cron.weekly/... — drop a script into one and it runs daily/weekly (a common way to add system-level periodic jobs). And there are shortcuts in place of the 5 fields:
@daily /opt/backup.sh # equivalent to 0 0 * * *
@hourly /opt/sync.sh
@reboot /opt/startup.sh # runs once each time the machine boots
at: run once in the future
cron is periodic. When you only need to run once at some time, use at:
echo "/opt/task.sh" | at 23:00 # run at 23:00 today
echo "/opt/task.sh" | at now + 1 hour
cron or systemd timer?
systemd (Article 15) can also schedule, using .timer units. Compared to cron:
- cron — simple, available everywhere, enough for most periodic work.
- systemd timer — more complex but more powerful: logs via journalctl, can depend on other units, runs catch-up jobs if the machine was off across the scheduled time (
Persistent=true).
For beginners and most needs, cron is enough and quicker to use.
🧹 Cleanup
crontab -r # delete the test jobs (if you only have test jobs)
Series wrap-up
Across 18 articles, you've gone from "what is Linux" to automating work on a server:
- Foundations (Articles 0–3): the practice environment, the shell, the FHS directory tree + "everything is a file", file operations.
- Daily tools (Articles 4–6): editors (nano/vim), text processing (grep/sed/awk), and a deep dive into pipe/redirect/data streams.
- The system (Articles 7–10): a deep dive into permissions (rwx), processes & signals, compression (tar), disk management.
- Administration (Articles 11–13): package management, user/group/sudo, networking.
- Real servers (Articles 14–17): SSH & file transfer, systemd, shell scripting, cron.
A few threads worth holding onto:
- Everything is a file — read processes, devices, configs with the same handful of commands.
- Small tools + pipes — combine simple commands into powerful operations, instead of hunting for one "does-it-all" command.
- Read the error message — most "Permission denied", "No space left", "connection refused" are solved with exactly the skills in this series (permissions, disk, networking).
- Least privilege — a regular user + sudo, keys instead of passwords, services running as their own user.
Where to go next
- Connecting with the other series: you now understand the Linux beneath a container (Docker series) and a cloud server (AWS series) — they're all Linux.
- Going deep in one area: advanced networking (firewall, iptables/nftables), security (SELinux/AppArmor, hardening), performance (resource monitoring, tuning).
- Configuration automation: Ansible to manage many servers at once — the natural next step after shell scripting.
Thanks for following the whole series. Linux isn't something you learn once and you're done, but the foundation in these 18 articles is enough to be confident on any Linux server, and to look up the rest yourself when needed (remember man — Article 1).
You've reached the end