Introduction
Cron is the classic task scheduler in Unix-like systems that allows you to automatically run commands and scripts on a schedule. With it, you can set up regular operations: creating backups, cleaning temporary files, sending reports, and much more. In this guide, you'll master the basics of cron: syntax, creating jobs, debugging, and typical use cases. After completing it, you'll be able to set up automation in Linux on your own.
Prerequisites
Before you begin, ensure that:
- You have access to a Linux terminal (locally or via SSH).
- The cron daemon is installed (usually pre-installed on most distributions). On Debian/Ubuntu, this is the
cronpackage; on CentOS/Fedora, it'scronie. - You have permission to run tasks (cron runs in the context of the current user).
- For testing, prepare a simple script, such as
~/test.shwith the following content:
Don't forget to make it executable:#!/bin/bash echo "Cron works: $(date)" >> /tmp/cron_test.logchmod +x ~/test.sh.
Step-by-Step Guide
Step 1: Understanding the crontab Format
A crontab file (cron job table) consists of lines, each defining a schedule and a command. The format is:
minute hour day_of_month month day_of_week command
- Minute: 0–59.
- Hour: 0–23.
- Day of month: 1–31.
- Month: 1–12.
- Day of week: 0–7 (0 and 7 are Sunday).
- Command: path to a script or command with arguments.
Special characters:
*— any value.*/N— step (e.g.,*/15in minutes means every 15 minutes).,— list (e.g.,0,30means at 0 and 30 minutes).-— range (e.g.,1-5means Monday through Friday).@reboot— run at system boot.
Examples:
0 * * * * /path/to/script.sh— every hour at minute 0.30 3 * * 1-5 /backup.sh— at 3:30 AM, Monday through Friday.0 0 1 * * /cleanup.sh— at 00:00 on the 1st of every month.
Step 2: Editing the crontab
Each user has their own crontab. To edit it:
- In the terminal, run:
crontab -e - On first run, the system may ask which editor to use (nano or vim). We recommend choosing
nanofor simplicity. - A text file (possibly empty) will open. This is your crontab.
💡 Tip: If you want to edit another user's crontab (e.g., root), use
sudo crontab -e. But be careful—jobs run as root have superuser privileges.
Step 3: Adding a Job
In the opened editor:
- Navigate to the end of the file.
- Add a line with the job. For example, to run the script
~/backup.shevery day at 2:30 AM:30 2 * * * /home/your_username/backup.sh - Ensure the path to the script is absolute (starts with
/). Cron does not use thePATHvariable from your shell, so specify full paths to all executables within the script.
⚠️ Important: Do not add extra characters (spaces, tabs) at the beginning of the line. Cron tolerates spaces after fields, but it's best to write without them.
Step 4: Checking and Managing Jobs
After saving the file, cron automatically loads the new configuration. To confirm the job was added:
- Run
crontab -l— you'll see a list of all jobs for the current user. - To remove a job, open crontab again (
crontab -e) and delete the corresponding line. - To completely clear the current user's crontab:
crontab -r(be careful, this is irreversible!).
To manage jobs for other users (root only), use:
sudo crontab -l -u username # view user's jobs
sudo crontab -e -u username # edit user's jobs
Step 5: Debugging and Logs
If a job doesn't run, look for the cause in the logs:
- Check the cron service status:
systemctl status cron # Debian/Ubuntu systemctl status crond # CentOS/Fedora
The service should be active (active (running)). - View cron logs. They are typically written to the system log:
grep CRON /var/log/syslog # Debian/Ubuntu grep CRON /var/log/cron # CentOS/Fedora
Or via journalctl:journalctl -u cron -f # follow logs in real time journalctl -u crond -f # for CentOS/Fedora - Check command output. By default, cron sends any output (stdout and stderr) to the user's local email. To capture it, add redirection to a file:
* * * * * /path/to/script.sh >> /tmp/script.log 2>&1
This saves both standard output and errors. - Verify script permissions. The script must be executable:
chmod +x /path/to/script.sh - Check the environment. Cron has a minimal environment (usually only
PATH=/usr/bin:/bin). If your script uses commands from other directories (e.g.,python3from/usr/local/bin), either specify full paths or setPATHin the crontab itself:PATH=/usr/local/bin:/usr/bin:/bin * * * * * /path/to/script.sh
Step 6: Useful Examples
Here are several common scenarios:
- Run every 5 minutes:
*/5 * * * * /usr/bin/wget -q https://example.com/heartbeat - Daily run at 1:00 AM:
0 1 * * * /home/user/daily_backup.sh - Run at 9:00 AM and 5:00 PM on weekdays:
0 9,17 * * 1-5 /home/user/work_start.sh - Run on the first day of the month at 2:30 AM:
30 2 1 * * /home/user/monthly_report.sh - Run at system boot (e.g., to start a background process):
@reboot /usr/local/bin/my_daemon --config /etc/my_daemon.conf - Run every minute (for testing):
* * * * * /home/user/test_cron.sh
💡 Tip: For complex schedules, use online crontab generators (e.g., crontab.guru)—they visually show when a job will run.
Verifying the Result
After adding a job:
- Confirm it appears in the list:
crontab -l. - If the job should have already run, check the logs (see Step 5) or the file that should have been created (e.g.,
/tmp/cron_test.log). - For a quick test, add a job that runs every minute (
* * * * * ...) and observe the result over a few minutes. - Ensure the script runs correctly when executed manually (outside cron)—this rules out errors in the script itself.
Common Issues
- "Cron doesn't run my script, but it works manually"
Cause: missing absolute paths in the script or insufficient permissions. Solution: use full paths for all commands inside the script and ensure the script is executable (chmod +x). - "There are no cron log entries for my job"
Cause: the cron daemon might not be running, or the job was added to another user's crontab. Solution: check the service status (systemctl status cron) and confirm you edited the correct user's crontab. - "The job runs but with errors"
Cause: cron's environment differs significantly from your interactive shell (missingPATH,HOME,USER, etc.). Solution: explicitly set needed variables in the crontab or inside the script, and use absolute paths. - "Cron ignores the
@rebootline"
Cause: some distributions (e.g., CentOS) require separate configuration for@reboot(in/etc/crontabor via systemd). Solution: use the standard format in the user crontab, or create a systemd timer for boot tasks. - "The job runs twice"
Cause: the job might be added both to the user crontab and the system crontab (/etc/crontab). Solution: check both locations and keep only one entry. - "Cron can't find the script interpreter (e.g., bash)"
Cause: an incorrect path to the interpreter in the script's first line. Solution: use#!/bin/bash(or#!/usr/bin/env bashfor portability) and ensure the interpreter file exists.