Bash Scheduling with Cron Jobs
Cron is Linux's built-in job scheduler, allowing you to automate Bash scripts on a time-based schedule. This post covers crontab syntax, practical scheduling examples, and how to capture output for debugging.
Automation is one of the most powerful skills you can develop as a network engineer or sysadmin. Once you have a Bash script that works, the next logical step is making it run automatically on a schedule. That is exactly what cron does, and it is built into virtually every Linux system you will ever touch.
What Is Cron?
Cron is a time-based job scheduler built into Linux and Unix systems. It runs in the background as a daemon process called crond and checks every minute to see if any scheduled tasks need to run. Those scheduled tasks are called cron jobs, and they live in a special file called a crontab (short for cron table).
You can think of cron as a built-in task scheduler, similar to Windows Task Scheduler, but far more flexible and controlled entirely from the command line.
The Crontab File
Every user on a Linux system can have their own crontab file. To view or edit your crontab, use the crontab command:
# Edit your crontab
crontab -e
# List your current cron jobs
crontab -l
# Remove your crontab entirely
crontab -rWhen you run crontab -e for the first time, Linux will ask you to choose a text editor. Nano is the friendliest option for beginners.
Understanding the Cron Syntax
Every cron job follows a strict five-field format, followed by the command you want to run:
# ┌───────────── minute (0 - 59)
# │ ┌───────────── hour (0 - 23)
# │ │ ┌───────────── day of month (1 - 31)
# │ │ │ ┌───────────── month (1 - 12)
# │ │ │ │ ┌───────────── day of week (0 = Sunday, 6 = Saturday)
# │ │ │ │ │
# * * * * * command to runEach field can contain:
- A specific number: run at that exact value (e.g.,
30in the minute field means "at 30 minutes past the hour") - An asterisk (
*): a wildcard meaning "every" (every minute, every hour, etc.) - A comma-separated list: run at multiple values (e.g.,
1,15means "on the 1st and 15th") - A step value with a slash: run at intervals (e.g.,
*/5means "every 5 units")
Practical Cron Job Examples
Let's look at some real-world examples to make this click:
# Run a backup script every day at 2:00 AM
0 2 * * * /home/user/scripts/backup.sh
# Run a script every 5 minutes
*/5 * * * * /home/user/scripts/check_links.sh
# Run a script every Monday at 9:00 AM
0 9 * * 1 /home/user/scripts/weekly_report.sh
# Run a script on the 1st of every month at midnight
0 0 1 * * /home/user/scripts/monthly_cleanup.sh
# Run a script at 8:00 AM and 6:00 PM every weekday
0 8,18 * * 1-5 /home/user/scripts/health_check.shA common gotcha: always use the full path to both your script and any commands inside it. Cron runs in a minimal environment and does not load your normal shell profile, so it may not know where to find commands referenced by name alone.
Capturing Output and Logging
By default, cron will try to email you the output of your jobs. On most servers, this is not configured. A better approach is to redirect output to a log file yourself:
# Append both stdout and stderr to a log file
0 2 * * * /home/user/scripts/backup.sh >> /var/log/backup.log 2>&1The 2>&1 part redirects error output (stderr) into the same place as standard output (stdout), so you capture everything in one file. This is invaluable for debugging when a cron job is not behaving as expected.
A Helpful Tool: Crontab Guru
If you are not yet comfortable reading cron expressions at a glance, bookmark crontab.guru. It is a free, interactive cron expression editor that translates cron syntax into plain English in real time. It is a genuine time saver.
What's Next
Now that you can schedule scripts to run automatically, the next natural topic is understanding how Bash handles input and output redirection in depth, including pipes, file descriptors, and how to chain commands together effectively. These concepts will make your scheduled scripts much more robust and easier to debug.