Linux crontab Command for Beginners: Schedule Jobs Without Surprise Tickets
The Linux crontab command lets you schedule commands to run automatically at specific times.
Quick version:
crontab -e
Then add a line like this:
0 2 * * * /home/alex/scripts/backup.sh
That means: run /home/alex/scripts/backup.sh every day at 2:00 AM.
If you came from Windows, cron is one of the Linux versions of Task Scheduler. It is used for backups, cleanup scripts, report exports, monitoring checks, certificate renewals, and all kinds of small jobs that quietly keep systems from becoming paperwork generators.
The beginner problem is that cron is also very good at failing quietly. A command works perfectly when you type it in your terminal, then does nothing at 2:00 AM because cron has a different environment, a different working directory, no interactive prompt, and absolutely no interest in your feelings.
This guide is the practical help desk version: how to read cron timing, edit a user crontab safely, avoid the common mistakes, and troubleshoot scheduled jobs without turning a five-minute task into an archaeology project.
Quick answer: schedule a Linux cron job
Open your crontab:
crontab -e
Add this example job:
*/15 * * * * /usr/bin/date >> /home/alex/cron-test.log 2>&1
Save and exit.
Check that it was installed:
crontab -l
That job runs every 15 minutes and appends the current date to /home/alex/cron-test.log.
The 2>&1 part sends errors to the same log file as normal output. That is not required, but it is one of those tiny habits that prevents future-you from muttering at a blank terminal.
What crontab means
A cron job is a scheduled command.
A crontab is the table of cron jobs for a user.
The crontab command is how you view, edit, install, or remove that table.
Common commands:
crontab -l # list your cron jobs
crontab -e # edit your cron jobs
crontab -r # remove your crontab
Be careful with crontab -r. It removes the whole crontab for that user. No confirmation on many systems. That is a bad surprise if you only meant to remove one old line.
If you are troubleshooting a job that runs as another user, you may need:
sudo crontab -u username -l
sudo crontab -u username -e
And if you are checking root’s crontab:
sudo crontab -l
That shows root’s scheduled jobs, not yours. This distinction matters. A lot.
Cron timing syntax explained
A basic cron line has five time fields, then the command:
minute hour day-of-month month day-of-week command
Example:
30 6 * * * /home/alex/scripts/report.sh
Read it as:
- minute:
30 - hour:
6 - day of month:
* - month:
* - day of week:
* - command:
/home/alex/scripts/report.sh
That runs every day at 6:30 AM.
The * means “every valid value.” Not every second. Cron is usually minute-based.
Here are useful examples:
0 * * * * run at the top of every hour
*/5 * * * * run every 5 minutes
0 9 * * 1 run every Monday at 9:00 AM
30 2 * * * run every day at 2:30 AM
0 0 1 * * run at midnight on the first day of each month
Day of week usually uses 0 or 7 for Sunday, 1 for Monday, and so on. Some systems also accept names like MON, but numbers are common in quick examples.
A safe first cron job
When you are learning cron, do not start with a deletion script, a database job, or anything that emails the entire company. Start with a harmless test.
Create a scripts folder:
mkdir -p ~/scripts
Create a simple script:
nano ~/scripts/cron-test.sh
Put this in it:
#!/usr/bin/env bash
set -euo pipefail
echo "Cron ran at $(date)" >> "$HOME/cron-test.log"
Make it executable:
chmod +x ~/scripts/cron-test.sh
Edit your crontab:
crontab -e
Add:
*/5 * * * * /home/alex/scripts/cron-test.sh >> /home/alex/cron-test-output.log 2>&1
Replace /home/alex with your real home directory. Do not paste /home/alex into production unless you enjoy tickets with your name on them.
After a few minutes, check:
ls -lah ~/cron-test.log ~/cron-test-output.log
cat ~/cron-test.log
If the file updates, cron is running the job.
Use full paths in cron jobs
This is the mistake that catches beginners constantly.
A command works here:
python3 ~/scripts/report.py
But fails in cron.
Why? Cron does not load your normal interactive shell setup the same way your terminal does. It may not have the same PATH. It may not understand ~ the way you expect in every position. It may start from a different working directory.
Better cron line:
0 6 * * * /usr/bin/python3 /home/alex/scripts/report.py >> /home/alex/report.log 2>&1
You can find command paths with:
command -v python3
command -v bash
command -v rsync
Use those full paths in your crontab when reliability matters.
Redirect output so failures have somewhere to go
Cron often sends output by local mail. On many beginner systems, that mail is not configured or not checked. So the job fails, cron technically tried to tell someone, and everyone still loses.
Add log redirection:
0 2 * * * /home/alex/scripts/backup.sh >> /home/alex/logs/backup.log 2>&1
That sends normal output and errors into one log file.
A better script can also create its own log directory:
mkdir -p /home/alex/logs
Then log a clear start and end:
echo "Starting backup at $(date)"
# backup command here
echo "Finished backup at $(date)"
If you support users or servers, this is basic ticket hygiene. A scheduled job with no logs is just a tiny haunted house you built for yourself.
Check whether cron is running
If a job did not run, first check the service.
On many Linux systems:
systemctl status cron
On some distributions, the service is named crond:
systemctl status crond
You can also search service names:
systemctl list-units | grep cron
If cron is stopped, jobs will not run. Very rude, but at least obvious.
Where cron logs live
Cron logging depends on the Linux distribution.
Common places to check:
grep CRON /var/log/syslog
sudo grep CRON /var/log/syslog
sudo journalctl -u cron
sudo journalctl -u crond
On some systems, cron activity may show in /var/log/cron:
sudo less /var/log/cron
Important: cron logs may only show that cron attempted to run the command. They might not show the command’s internal error unless you redirected output to a log file.
That is why this pattern is worth memorizing:
* * * * * /path/to/script.sh >> /path/to/script.log 2>&1
Environment variables are different in cron
Your terminal might know variables like:
echo $PATH
echo $HOME
echo $SHELL
Cron may have a much smaller environment.
If a script depends on something like an API key, app path, virtual environment, Node version manager, Python environment, or custom shell profile, it may work by hand and fail from cron.
A simple debugging trick:
* * * * * env > /home/alex/cron-env.txt
Wait a minute, then read the file:
cat /home/alex/cron-env.txt
Compare that to your interactive environment:
env > /home/alex/terminal-env.txt
Do not paste secrets into tickets or screenshots. The point is to understand the difference, not create a new incident.
Common beginner crontab mistakes
Mistake 1: Editing the wrong user’s crontab
You run:
crontab -e
Then wonder why the job does not have permission to write under /var/www.
Maybe it needed to run as www-data, deploy, or root. Or maybe it should not be writing there at all. Check who owns the files, then choose the right user on purpose.
Mistake 2: Forgetting executable permission
If your crontab runs a script directly:
0 3 * * * /home/alex/scripts/cleanup.sh
The script needs execute permission:
chmod +x /home/alex/scripts/cleanup.sh
Or call it with Bash explicitly:
0 3 * * * /usr/bin/bash /home/alex/scripts/cleanup.sh
Mistake 3: Using relative paths
This is fragile:
0 3 * * * ./cleanup.sh
This is better:
0 3 * * * cd /home/alex/scripts && /usr/bin/bash cleanup.sh >> /home/alex/logs/cleanup.log 2>&1
Even better, make the script handle its own paths clearly.
Mistake 4: Assuming cron uses your local timezone
Most servers use the system timezone. Check it:
timedatectl
If a job ran at the “wrong” time, verify timezone before blaming cron, the server, the vendor, the intern, or the nearest printer.
Mistake 5: Scheduling something too often
This looks harmless:
* * * * * /home/alex/scripts/sync.sh
It runs every minute.
If the script sometimes takes longer than a minute, jobs can overlap. Now you have two copies running, then three, then a help desk ticket titled something like “server slow???”
Use locking for jobs that must not overlap, or schedule them less aggressively.
Crontab vs system cron folders
You may also see these directories:
/etc/cron.hourly/
/etc/cron.daily/
/etc/cron.weekly/
/etc/cron.monthly/
And files like:
/etc/crontab
/etc/cron.d/some-job
These are system-level cron locations. They are different from a user’s personal crontab.
One key difference: files in /etc/crontab and /etc/cron.d/ often include a user field.
Example:
0 2 * * * root /usr/local/bin/nightly-maintenance
That root field is not used in a normal user crontab. If you copy lines between system cron and user crontabs without noticing that difference, you can break things in weird ways.
For beginners, start with crontab -e unless you have a clear reason to touch system cron files.
A help desk troubleshooting checklist
When someone says “the scheduled job did not run,” work through this:
- Which user owns the crontab?
crontab -l
sudo crontab -u username -l
sudo crontab -l
- Is the cron service running?
systemctl status cron
systemctl status crond
- Does the timing mean what the requester thinks it means?
minute hour day-of-month month day-of-week
- Does the script run manually as the same user?
sudo -u username /path/to/script.sh
- Are full paths used for commands and files?
command -v bash
command -v python3
- Is output redirected to a log?
>> /path/to/job.log 2>&1
- Do system logs show cron attempted the job?
sudo journalctl -u cron
sudo grep CRON /var/log/syslog
- Could jobs be overlapping?
ps aux | grep script-name
That checklist solves a lot of “cron is broken” tickets where cron is, sadly, innocent.
Practice this safely
Cron is worth practicing because scheduled jobs show up everywhere in real support work. Backups, reports, cleanup tasks, certificate renewals, monitoring checks, and one-off “temporary” jobs from 2021 that nobody wants to admit still exist.
Practice the safe version first:
- list existing jobs with
crontab -l - create a harmless job with
crontab -e - redirect output to a log
- verify the log changed
- remove only the test line when done
Do not learn cron for the first time on a production database server at 4:55 PM. That is how keyboards learn to fly.
If you want a safer place to build the muscle memory, practice Linux command-line basics in Shell Samurai. The point is to get comfortable reading commands, editing files, checking logs, and verifying results before the real ticket queue is staring at you.
Quick crontab reference
crontab -l # list your cron jobs
crontab -e # edit your cron jobs
crontab -r # remove your whole crontab; be careful
sudo crontab -u user -l # list another user's cron jobs
sudo crontab -u user -e # edit another user's cron jobs
systemctl status cron # check cron service on many systems
sudo journalctl -u cron # check cron logs on systemd systems
Cron is not complicated once you slow down and verify the boring parts: user, time, path, environment, output, and logs. That is most Linux troubleshooting in miniature, which is exactly why it is a good beginner sysadmin skill.
Practice This in a Real Terminal
Shell Samurai gives you safe Linux missions so the commands actually stick. Chapter 1 is free; the full practice path is a one-time purchase, not another subscription.