Host Your Own AI Agent with OpenClaw - Free 1-Click Setup!

Crontab Syntax on Linux: A Practical Guide For 2026

You’ve got a backup script. It works when you run it by hand. Now you need it to run at 2 AM every night without you babysitting the terminal. That’s where cron comes in, and getting the crontab syntax right is the difference between a script that fires on schedule and one that silently does nothing while you sleep.

This guide covers everything you need: crontab format and field values, the special characters that make scheduling flexible, the handful of crontab commands you’ll actually use, and real examples you can copy and modify. No filler, no fluff.

What Is Crontab and a Cron Job

Three terms get thrown around interchangeably, and they shouldn’t be.

Cron daemon (crond) is the background process that wakes up every minute, checks for scheduled work, and runs whatever’s due. It’s been doing this on Unix systems since the 1970s. You don’t interact with it directly.

Cron job is any single task you’ve scheduled through cron. A database backup at midnight, a log rotation on Sundays, a health-check ping every five minutes. Each one is a cron job.

Crontab (short for “cron table”) is the file where those jobs live. One line per job. Each line tells the cron daemon exactly when to run a command and what command to run.

What Is Crontab Syntax

Crontab syntax is the structured format you use to define when a cron job should fire. Every line in your crontab file follows the same pattern: five time/date fields, then the command. The cron daemon reads these lines, parses the fields, and matches them against the current system time once per minute. Get the syntax wrong and nothing happens. No error, no warning. Just silence.

Crontab Format and Field Values

Every crontab entry uses five fields before the command. They always appear in this order:

FieldAllowed Values
Minute0-59
Hour0-23
Day of month1-31
Month1-12
Day of week0-6 (0 = Sunday; on some systems, 7 also means Sunday)
CommandThe shell command to execute

All five fields are mandatory. If you don’t care about a particular field, fill it with an asterisk (*). Leaving a field blank breaks the entry and cron won’t tell you about it.

Crontab Special Characters Explained

Raw numbers get you only so far. These special characters make cron expressions flexible enough to handle real scheduling needs:

SymbolWhat It DoesExample
* (asterisk)Matches every possible value for that field* in the hour field = run every hour
, (comma)Separates a list of specific values1,3,5 in day-of-week = Mon, Wed, Fri
- (hyphen)Defines a range of consecutive values9-17 in the hour field = 9 AM through 5 PM
/ (slash)Sets a step/interval value*/10 in minute field = every 10 minutes
LLast day of month or last specific weekday1L in day-of-week = last Monday of the month
WNearest weekday to the given day15W in day-of-month = nearest weekday to the 15th
# (hash)Nth occurrence of a weekday in the month2#3 = third Tuesday of the month
? (question mark)No specific value; used in day fields? in day-of-month = any day

Quick note: L, W, #, and ? aren’t supported by every cron implementation. Standard Linux crontab (Vixie cron) doesn’t recognize them. You’ll find them in Quartz-based schedulers and some extended cron variants. Stick with *, commas, hyphens, and slashes if you want portable syntax.

Essential Crontab Commands

You only need four crontab commands. That’s it. Here they are:

  • crontab -e opens your crontab file for editing. If you don’t have one yet, it creates a fresh file. First time around, it’ll ask which text editor you prefer.
  • crontab -l lists all your current crontab entries. Use it to verify what’s actually scheduled, because guessing is how things break at 3 AM.
  • crontab -r deletes your entire crontab file. Not a single entry. The whole file. Gone. No confirmation prompt.
  • crontab -ri does the same as -r but asks you first. Use this one. Always.

That covers 99% of what you’ll do. Edit, list, and occasionally delete.

How to Use Crontab With Examples

Theory’s done. Let’s build actual crontab entries. Open your crontab file:

crontab -e

Your system will ask you to pick an editor if this is your first time. Pick nano if you want the least friction. You’ll land in a text file where each new line becomes a new cron job.

One thing to remember: crontab uses your system’s current timezone. If your server’s set to UTC and you’re scheduling for “9 AM,” that’s 9 AM UTC, not your local time. Check with timedatectl if you’re unsure.

Schedule a Cron Job at a Specific Time

Say you want to run a shell script on June 10th at 8:30 AM. Here’s the entry:

30 08 10 06 * /home/user/superbackup.sh

Minute 30, hour 08, day 10, month 06, any day of week. Straightforward. The asterisk in the day-of-week field means “don’t care what day it falls on.”

View Crontab Entries With crontab -l

Want to see what’s already scheduled? Run:

crontab -l

This dumps every line in your crontab file to the terminal. If the output is empty, you have no cron jobs. Simple.

Edit Crontab Entries

Need to change a schedule or fix a path? Same command you used to create it:

crontab -e

Find the line, edit it, save, exit. The cron daemon picks up changes automatically. No restart needed.

Run a Cron Job Every Minute

Five asterisks, then your command. That’s the every-minute pattern:

* * * * * /home/user/systemhealthcheck.sh

This fires once per minute, every minute, every hour, every day. Use it for monitoring scripts or rapid polling. Don’t use it for anything heavy, or your server will hate you.

Schedule a Daily Cron Job

The @daily shortcut runs a command once per day at midnight (00:00):

@daily /home/user/systemcleanup.sh

It’s cleaner than writing 0 0 * * * and means the same thing. There’s also @weekly (Sunday at midnight), @hourly (minute 0 of every hour), and @annually (January 1st at midnight).

Schedule a Cron Job for a Time Range

Need a script to run during business hours only? Use a hyphen in the hour field:

00 08-17 * * * /home/user/sync.sh

This runs at the top of every hour from 8 AM through 5 PM, every day. Want weekends only? Add a day-of-week range:

00 08-17 * * 6-0 /home/user/sync.sh

Now it fires only on Saturday (6) through Sunday (0).

Monthly and Yearly Cron Schedules

The @monthly shortcut runs a job at midnight on the 1st of every month:

@monthly /home/user/monthlyreport.sh

Equivalent to 0 0 1 * *. And @yearly (or @annually) fires on January 1st at midnight. Good for certificate renewals, annual log archives, or anything you need exactly once a year.

Run a Cron Job Multiple Times a Day

Comma-separated values let you hit multiple specific times. Five times a day at noon, 3 PM, 5 PM, 7 PM, and 9 PM:

0 12,15,17,19,21 * * * /home/user/report.sh

Each value in the hour field is a separate trigger. The minute field is 0, so it runs at the top of each of those hours.

Run a Command After System Reboot

The @reboot directive runs a command once, right after the system starts up:

@reboot /home/user/startservices.sh

Perfect for launching background daemons, re-establishing SSH tunnels, or starting monitoring agents that don’t have systemd service files. It only fires on boot, not on cron daemon restarts.

Crontab File Location on Linux

Where the actual crontab files sit on disk depends on your OS:

  • Debian/Ubuntu/var/spool/cron/crontabs/
  • Red Hat/CentOS/Fedora/var/spool/cron/
  • macOS/var/at/tabs/

You can peek at these directly, but editing them by hand bypasses cron’s syntax checking. Stick with crontab -e.

Additional Crontab Configuration

The basics handle most use cases. But when your cron jobs start multiplying, you’ll want logging, email control, and proper environment setup.

Create a Crontab Log File

By default, cron job output vanishes unless you capture it. Redirect stdout and stderr to a log file:

* * * * * /home/user/script.sh >> /var/log/cronjob.log 2>&1

The >> appends instead of overwriting, so you keep a running history. The 2>&1 sends error messages to the same file as standard output. Without this, your script can fail silently for weeks and you’ll never know until something downstream breaks.

Disable Crontab Email Notifications

Cron sends an email to the user for every job that produces output. On a busy system, that’s a lot of local mail nobody reads. Suppress it by appending:

>/dev/null 2>&1

Add this to the end of any cron job line. It sends both stdout and stderr to /dev/null. Just make sure you actually have logging set up separately, or you’ll be flying blind.

Crontab Environment Variables

Cron doesn’t load your shell profile. That means your PATH, SHELL, and other environment variables are minimal by default. Define them at the top of your crontab file:

  • PATH – tells cron where to find executables. Default is usually just /usr/bin:/bin, which is why /usr/local/bin scripts fail unexpectedly.
  • SHELL – sets which shell cron uses. Defaults to /bin/sh, not bash. If your scripts use bash features, set this to /bin/bash.
  • LOGNAME – the username that owns the crontab. Pulled from /etc/passwd.
  • HOME – the home directory for the crontab owner. Also from /etc/passwd.

Set them like any shell variable at the top of your crontab, before your job entries:

SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin
* * * * * /home/user/script.sh

This is the single most common reason cron jobs work interactively but fail when scheduled. Check your PATH first. Always.

Scroll to Top