Guides

crontab -e, -l and -r explained: editing, listing and clearing a user's cron jobs

crontab -e edits your scheduled jobs, -l lists them, -r deletes all of them with no confirmation. The five time fields, cron's own environment and the %-escaping trap.

Published ~8 min read

Short answer: crontab -e opens your personal crontab in an editor so you can add or change scheduled jobs; crontab -l lists what is currently in it; crontab -r deletes it entirely, with no confirmation. Each user has one crontab, five time fields plus a command, and cron reads it again on its own after crontab -e saves — there is nothing to restart.

CommandDoes
crontab -eEdit your own crontab (creates it if you have none)
crontab -lList your own crontab
crontab -rDelete your own crontab, no confirmation
crontab -r -iSame, but asks “y/n” first
sudo crontab -e -u aliceEdit another user's crontab
sudo crontab -l -u aliceList another user's crontab
crontab -l > backup.cronSave a copy of your crontab to a file
crontab backup.cronReplace your crontab with the contents of that file
EDITOR=nano crontab -eUse nano instead of the default editor just once

What is crontab?

crontab is both the file format and the command that manages it. “The crontab” is the list of scheduled jobs for one user, stored under /var/spool/cron/crontabs/ on Debian and Ubuntu (/var/spool/cron/ on Rocky Linux and AlmaLinux). You never edit those files directly — the crontab command is the only supported way in, because it checks the syntax before saving and tells the already-running cron daemon to re-read the file. Editing the spool file by hand, or with the wrong permissions, is what produces WRONG FILE OWNER or INSECURE MODE warnings and a crontab that cron quietly ignores.

crontab -e: adding and changing jobs

Debian · Ubuntu · Rocky · AlmaLinux
crontab -e

The first time you run it with no EDITOR or VISUAL set, Debian and Ubuntu ask you to pick an editor from a numbered list (nano is usually the default choice,1); Rocky and AlmaLinux open vi directly. Set it permanently in your shell profile:

~/.bashrc or ~/.profile
export EDITOR=nano

Each line is five time fields, then the command to run:

crontab format
# .---------------- minute (0-59)
# |  .------------- hour (0-23)
# |  |  .---------- day of month (1-31)
# |  |  |  .------- month (1-12)
# |  |  |  |  .---- day of week (0-7, both 0 and 7 are Sunday)
# |  |  |  |  |
  */5 *  *  *  *  /usr/local/bin/check.sh
  30  2  *  *  *  /usr/local/bin/backup.sh >> /home/you/backup.log 2>&1
  0   9  *  *  1  /usr/local/bin/weekly-report.sh

Save and exit the editor the normal way for that editor (Ctrl+O then Ctrl+X in nano, :wq in vi). crontab parses the file before installing it and refuses a broken one with errors in crontab file, can't install, dropping you back into the editor to fix the line it did not understand — so a typo never silently disables the whole file.

ShortcutMeans
@rebootOnce, when the cron daemon starts (usually at boot)
@yearlySame as 0 0 1 1 *
@monthlySame as 0 0 1 * *
@weeklySame as 0 0 * * 0
@dailySame as 0 0 * * *
@hourlySame as 0 * * * *
*/5Every 5 units (minute, hour, etc. depending on the field)
1-5A range: Monday to Friday in the day-of-week field
1,15A list: the 1st and the 15th in the day-of-month field

Paste the five fields into the cron expression generator to read a schedule back in plain English and see its next run times before you save it — catching “every minute from 2:00 to 2:59” (* 2 * * *) instead of once at 2:00 (0 2 * * *) is the single most common crontab mistake.

crontab -l: what is actually scheduled

your own crontab
crontab -l

With no crontab at all it prints no crontab for you (or, on some systems, exits silently with nothing). This is the first thing to check when a job “never runs”: a line saved into the wrong crontab is the most common reason, covered in cron job not running.

sudo crontab -l vs crontab -l vs -u

These three commands open three different files, and mixing them up is the second most common crontab mistake:

  • crontab -l as yourself shows your crontab only.
  • sudo crontab -l shows root’s crontab, not yours with extra privileges — sudo changes who the command runs as, and crontab always acts on the current user unless told otherwise.
  • sudo crontab -l -u alice shows alice’s crontab. Only root (or a user in the crontab group where that restriction is configured) may use -u for a user other than themselves.

crontab -r: deleting a crontab

danger: no confirmation by default
crontab -r          # deletes your entire crontab immediately
crontab -r -i       # asks "y" first (Debian, Ubuntu; not every crontab(1) supports -i)

There is no undo and no trash. To remove one job, use crontab -e and delete that line instead; -r is for deleting everything. Back up first if the crontab is worth keeping:

back up, then restore if needed
crontab -l > ~/crontab-backup-$(date +%F).txt
crontab ~/crontab-backup-2026-10-01.txt   # restores from a saved file

/etc/crontab and /etc/cron.d: the exception with a user field

Everything above is a user crontab, managed only through the crontab command. The system has a second kind, edited as root with a normal text editor: /etc/crontab and files under /etc/cron.d/. Both need a sixth field, the user to run the job as, right after the five time fields:

/etc/crontab
# m h  dom mon dow  user   command
  30 2  *   *   *    root   /usr/local/bin/backup.sh

Mixing the two up is a classic failure: paste a /etc/crontab line into crontab -e and the word root becomes the command, which fails with root: not found; leave the user field out of an /etc/cron.d/ file and cron reads the first word of your own command as the user name instead.

crontab’s own environment

A crontab can set variables at the top, before any job lines, which apply to every job below them:

crontab -e
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MAILTO=""

15 3 * * * /usr/local/bin/backup.sh >> /home/you/backup.log 2>&1
  • PATH defaults to /usr/bin:/bin only, which is why a command that works in your terminal can be “not found” in cron; write it out in full as above, or use absolute paths in each job.
  • MAILTO is where cron sends a job’s output, by default the crontab’s owner through the system’s mail setup. Most servers have none, so output silently vanishes unless you redirect it yourself (as in the example) or set MAILTO=you@example.com with a mail transfer agent installed.
  • These lines are read literally: PATH=$HOME/bin:$PATH sets PATH to that exact text, because cron does not expand variables here the way a shell does.

The % character ends a crontab line

An unescaped % in a job turns into a newline and everything after it becomes the command’s standard input, not part of the command. Escape it as \% whenever a job uses date +%F, find -printf or a URL-encoded string:

crontab -e
# broken: cron cuts the command at the %
0 3 * * * tar czf /backup/db-$(date +%F).tar.gz /var/lib/mysql

# correct
0 3 * * * tar czf /backup/db-$(date +\%F).tar.gz /var/lib/mysql

Scheduling cron jobs from a script

A deploy script can add a line without opening an editor at all, by piping the combined output through crontab - (a single dash reads from standard input):

append a line without crontab -e
(crontab -l 2>/dev/null; echo "*/10 * * * * /usr/local/bin/check.sh") | crontab -

The 2>/dev/null swallows the “no crontab for you” message on a user who has none yet, so the command works either way. Run this once, not on every deploy, or the same line piles up every time.

When a systemd timer fits better

crontab has no built-in logging beyond “it started” (see journalctl for reading that log), no way to catch up a job that was missed while the server was off, and on Debian and Ubuntu only one timezone for the whole file. A systemd timer answers all three and is worth the extra setup for anything that matters; see creating a systemd service for the unit and timer files.

Frequently asked

What does crontab -e do?

It opens your personal crontab in a text editor (nano by default on Debian and Ubuntu, vi on Rocky and AlmaLinux) so you can add, change or remove scheduled jobs. It checks the syntax before saving and tells the already-running cron daemon to re-read the file — there is nothing to restart afterward.

What is the difference between crontab -l and sudo crontab -l?

crontab -l lists your own crontab. sudo crontab -l lists root's crontab, not yours with extra privileges, because sudo changes who the command runs as. To see another specific user's crontab, use sudo crontab -l -u username.

Does crontab -r ask for confirmation?

No, not by default — it deletes your entire crontab immediately with no undo. Some systems' crontab also accepts -i, which asks for a yes/no first. Back up first with crontab -l > backup.txt if the crontab is worth keeping.

Why does my crontab line with date +%F not work?

An unescaped % ends a crontab line early; cron turns it into a newline and sends the rest to the command's standard input instead of treating it as part of the command. Write \% instead of % wherever a job uses date, find -printf or a URL-encoded string.

Does crontab -e edit /etc/crontab?

No. crontab -e only ever edits the current user's own crontab under /var/spool/cron/. /etc/crontab and files under /etc/cron.d/ are a separate kind, edited directly with a text editor as root, and need an extra user field right after the five time fields that a user crontab does not have.

Related articles

All guides