Provided by: systemd-cron_2.6.0-1_amd64 bug

NAME

       crontab — tables for driving systemd-cron

DESCRIPTION

       A  crontab file contains instructions for systemd-cron of the general form "run this command at this time
       on this date".  Each user has their own crontab, and commands in any given crontab will  be  executed  as
       the user who owns it.

       Blank  lines  and  leading  spaces and tabs are ignored.  Lines whose first non-space character is a hash
       (‘#’) are comments, and are ignored.  Note that comments are  not  allowed  on  the  same  line  as  cron
       commands, since they will be taken to be part of the command.  Similarly, comments are not allowed on the
       same line as environment variable settings.

       An active line in a crontab will be either an environment setting or a cron command.  The crontab file is
       parsed  from  top to bottom, so any environment settings will affect only the cron commands below them in
       the file.  An environment setting takes the form
             name = value
       where the white-space around the equals sign (‘=’) is  optional,  and  any  subsequent  non-leading  non-
       trailing  white-space will be part of the value assigned to name.  value may be placed in matching quotes
       (‘'’ or ‘"’), to preserve embedded leading or trailing white-space.  The value string is not  parsed  for
       environmental substitutions or replacement of variables, thus lines like
             PATH = $HOME/bin:$PATH
       will not work as you might expect.  And neither will this work:
             A=1
             B=2
             C=$A $B
       There  will not be any substitution for the defined variables in the last value (i.e., C will be "$A $B",
       not "1 2").

       In PATH, tilde-expansion is performed on elements starting with "~/", so this works as expected:
             SHELL=/bin/bash
             PATH=~/bin:/usr/bin/:/bin

   Special variables
       SHELL, PATH, USER, LOGNAME, HOME, LANG
               Those are set up automatically by systemd,  see  systemd.exec(5).   SHELL  defaults  to  /bin/sh.
               SHELL and PATH may be overridden by settings in the crontab.

       MAILTO  When  sending output from a job, systemd.cron(7) will look at MAILTO: if defined, mail is sent to
               this email address.  MAILTO may also be used to direct mail to multiple recipients by  separating
               recipient  users  with  a  comma (‘,’).  If MAILTO is set but empty (MAILTO="", MAILTO=), no mail
               will be sent.  Otherwise mail is sent to the crontab's owner.
               By default, this mail contains systemctl status and the full log for the failed run, copied  from
               the journal.

       MAILFROM
               When  sending  output from a job, systemd.cron(7) will look at MAILFROM: if defined, mail is sent
               from this email address.  Otherwise it's seen as being sent by "root".

       CRON_MAIL_SUCCESS
               Control if (when) to send mail with output from successful jobs.
               nonempty, non-empty:  mail is only sent if the job left  anything  in  the  journal  (i.e.  wrote
                                     something  to  the  standard output or error streams); this is the default,
                                     and matches classic cron
               always, yes, true, 1: always send mail
               never, no, false, 0:  never send mail for a successful job

               Mail is always sent for failed jobs.

       CRON_MAIL_FORMAT
               Control the format of the content of cron-job-related messages.
               normal:                  systemctl status + journalctl output (incl.  time,  process  names,  the
                                        usual) for the run; this is the default
               nometadata, no-metadata: raw  journal  contents  (-o  cat: just standard output + error streams);
                                        this matches classic cron

               CRON_MAIL_SUCCESS and CRON_MAIL_FORMAT, if changed in /etc/crontab, are remembered for all  other
               crontabs  (/etc/cron.d,  /etc/anacron,  users'  crontabs)  and act as an administrator-controlled
               default.  They can be set to inherit to get that default back.

       CRON_INHERIT_VARIABLES
               In the top-level /etc/crontab: a  white-space-separated  list  of  variables  (including  control
               statements  that  get  removed  from  the  environment otherwise) to remember into other crontabs
               (/etc/cron.d,  users'  crontabs;  not  /etc/anacron).    This   allows   instituting   a   global
               RANDOM_DELAY/SHELL/&c. default policy.
               Elsewhere: ignored.

       RANDOM_DELAY
               (in minutes) environment variable translated to RandomizedDelaySec=.

       DELAY   (in  minutes)  environment  variable translated to OnBootSec=.  This works like the anacrontab(5)
               delay and makes systemd wait the given amount of minutes after boot  before  starting  the  unit.
               This  value can also be used to spread out the start times of @daily/@weekly/@monthly/&c. jobs on
               an always-on system.

       START_HOURS_RANGE
               (in hours) environment variable translated to the hour component of OnCalendar=.   This  variable
               is     inherited    from    anacrontab(5),    but    also    supported    in    crontab(5)s    by
               systemd-crontab-generator(8).   anacron(8)  expects  a   time   range   like   "start-end",   but
               systemd-crontab-generator(8)  only  uses the starting hour of the range as reference.  Unless you
               set this variable, all @daily/@weekly/@monthly/&c. jobs will run at midnight.  If you do set this
               variable and the system was off during the hours defined in the range, persistent jobs will start
               at boot.

       PERSISTENT
               This boolean flag can override the generator's default heuristic:
                 yes:  force all further jobs to be persistent
                 auto: only recognize @ keywords to be persistent (this is the default)
                 no:   force all further jobs to not be persistent

       TZ, CRON_TZ
               The job is scheduled in this time-zone instead of in the system time-zone.  Must be a  full  IANA
               time-zone  name  (as found under /usr/share/zoneinfo), or empty to reset to the default timezone;
               otherwise no special semantics.  Always passed to the job.

       BATCH   This boolean flag is translated to options  CPUSchedulingPolicy=idle  and  IOSchedulingClass=idle
               when set.

       CRON_BATCH_LOADAVG_BELOW
               If  set  and  nonempty, delay starting the job until the 1-minute system load average drops below
               the set value.  All jobs using this option join a global queue scheduling a random  eligible  job
               every at-least-30 seconds.

       CRON_BATCH_THROTTLE_GROUP
               If  set  and  nonempty,  all  jobs  with  the  same  value form a group where no two jobs can run
               concurrently and no job is started within 5 minutes of another exiting.
               If combined with CRON_BATCH_LOADAVG_BELOW, the  job  joins  its  CRON_BATCH_THROTTLE_GROUP  queue
               only, but the load threshold still applies.
               See “EXAMPLES, CRON_BATCH_…”.

   The format of a cron command
       is  the  same  as  the  one defined by the classic cron daemon.  Each line has five time and date fields,
       followed by a command, followed by a new-line character.   The  system  crontab  (/etc/crontab)  and  the
       packages'  crontabs  (/etc/cron.d/*)  use  the  same  format, except that the username for the command is
       specified between the time/date fields and the command.  Fields may be separated by spaces or tabs.

       Commands are executed by systemd(1) when the minute, hour, and month-of-year  fields  match  the  current
       time,  and  when  at least one of the two day fields (day-of-month or day-of-week) match the current time
       (see “Note below”).  The time and date fields are:
               field          allowed values
             ───────────────────────────────────────────────────
               minute         0-59
               hour           0-23
               day-of-month   1-31
               month          1-12 (or names, see below)
               day-of-week    0-7 (Sun is 0 or 7, or use names)

       A field may be an asterisk (‘*’), which always stands for "first-last".

       Ranges of numbers are allowed.  Ranges are two numbers separated with  a  hyphen  (‘-’).   The  specified
       range is inclusive.  For example, 8-11 for an hours entry specifies execution at hours 8, 9, 10, and 11.

       A random value (within the legal range) may be obtained by using the tilde (‘~’) character instead of the
       hyphen.   The interval of the random value may be specified explicitly, for example 0~30 will result in a
       random value between 0 and 30, inclusive.  If either (or both) of the numbers on the sides of the ‘~’ are
       omitted, the appropriate limit (low or high) for the field will be used.

       Lists are allowed.  A list is a set of numbers (or  ranges)  separated  by  commas.   Examples:  1,2,5,9,
       0-4,8-12.

       Step  values can be used in conjunction with ranges.  Following a range with "/number" specifies skips of
       number's value through the range.  For example, 0-23/2 can be used in the hours field to specify  command
       execution   every   other   hour   (the   alternative   in   Version   7   AT&T  UNIX  standard  form  is
       0,2,4,6,8,10,12,14,16,18,20,22).  Steps are also permitted after an asterisk,  so  if  you  want  to  say
       "every two hours", just use */2.

       Names can also be used for the month and day-of-week fields.  Use at least the first three letters of the
       particular day or month (case doesn't matter).  Ranges or lists of names are not allowed.

       The  rest  of the line, after the fields, specifies the command to be run.  The entire command portion of
       the line will be executed by /bin/sh or by the shell specified in the SHELL variable of the crontab file.

       If the command contains an unescaped percent (‘%’) character, it  is  instead  split  thereon:  the  part
       before  is run by the shell, the part after is given on the standard input stream, with each subsequent %
       replaced by a new-line.  %s can be escaped as "\%", and produce a literal %.

   Note
       The day of a command's execution can be specified by two fields — day-of-month and day-of-week.  If  both
       fields  are  restricted  (i.e.,  aren't *), the command will be run when either field matches the current
       time.  For example,
             30 4 1,15 * 5 command
       would run command at 4:30 am on the 1st and 15th of each month, plus every  Friday.   One  can,  however,
       achieve  the  desired  result  by adding a test to the command (see the last example in “EXAMPLES, User's
       crontab below”).

       Instead of the first five fields, one of eight special strings may appear:
               string      meaning                equivalent
             ────────────────────────────────────────────────
               @reboot     Run once, at startup   (none)
               @yearly     Run once a year        0 0 1 1 *
               @annually
               @monthly    Run once a month       0 0 1 * *
               @weekly     Run once a week        0 0 * * 0
               @daily      Run once a day         0 0 * * *
               @midnight
               @hourly     Run once an hour       0 * * * *

       Please note that startup, as far as @reboot is concerned, may be before some  system  daemons,  or  other
       facilities, were started.

EXAMPLES

   User's crontab
       # use /bin/bash to run commands, instead of the default /bin/sh
       SHELL=/bin/bash
       # mail errors to 'paul', no matter whose crontab this is
       MAILTO=paul
       #
       # run five minutes after midnight, every day
       5 0 * * *       ~/bin/daily.job >> ~/tmp/out 2>&1
       # run at 2:15pm on the first of every month
       15 14 1 * *     ~/bin/monthly
       # run at 10 pm on weekdays, annoy Joe
       # runs 'mail -s "It's 10 pm" joe', with 'Joe,\n\nWhere are your kids?\n' on stdin
       0 22 * * 1-5    mail -s "It's 10pm" joe%Joe,%%Where are your kids?%
       23 0-23/2 * * * echo "run 23 minutes after midn, 2am, 4am …, everyday"
       5 4 * * sun     echo "run at 5 after 4 every sunday"
       # Run on every second Saturday of the month
       0 4 8-14 * *    test $(date +\%u) -eq 6 && echo "2nd Saturday"

   System crontab
       # /etc/crontab: system-wide crontab
       # Unlike any other crontab you don't have to run the `crontab'
       # command to install the new version when you edit this file
       # and files in /etc/cron.d. These files also have username fields,
       # that none of the other crontabs do.

       SHELL=/bin/sh
       PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

       # m h dom mon dow user  command
       17 * * * *  root  cd / && run-parts --report /etc/cron.hourly
       25 6 * * *  root  test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
       47 6 * * 7  root  test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
       52 6 1 * *  root  test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
       #

       This  is  only  an  example: systemd-crontab-generator(8) uses native units listed in systemd.cron(7) for
       those jobs instead; if you add those lines, your jobs may run twice.

   CRON_BATCH_…
             CRON_BATCH_THROTTLE_GROUP=first
              0 0 * * * sleep  2m # a
              0 0 * * * sleep  4m # b
              0 0 * * * sleep  4m # c
             17 0 * * * sleep  2m # L

             CRON_BATCH_THROTTLE_GROUP=second
              2 0 * * * sleep  3m # q
              2 0 * * * sleep 11m # w
       may result in any of the following job runs (horizontal axis is time, one minute per column,  other  jobs
       unaffected):
             00   05   10   15   20   25   30
             aa     cccc     bbbb     LL
               qqq     wwwwwwwwwww

             aa     cccc     bbbb     LL
               qqq     wwwwwwwwwww

             cccc     bbbb     LL     aa
               wwwwwwwwwww     qqq

             cccc     aa     bbbb     LL
               wwwwwwwwwww     qqq

SEE ALSO

       crontab(1), systemd.cron(7), systemd-crontab-generator(8)

       Some extra settings can only be tweaked with
             systemctl edit cron-schedule.{timer,service}

LIMITATIONS

       The  crontab  syntax  does  not  make  it possible to define all possible periods one could imagine.  For
       example, it is not straightforward to define the last weekday of a month.  If a task needs to be run in a
       specific period of time that cannot be represented in a crontab, the best approach would be to  have  the
       job  itself  check  the date and time information and continue execution only if the current time matches
       the desired one.

       systemd-crontab-generator(8) doesn't support the following Vixie Cron features:
        spawning forking daemons, the systemd.service(5) units are all configured with Type=oneshot
        Vixie Cron requires that each crontab entry end in a new-line.  If the  last  entry  in  a  crontab  is
         missing    a    new-line,    Vixie    Cron    will   consider   it   (at   least   partially)   broken.
         systemd-crontab-generator(8) considers this crontab valid.
        The parsing of quoting of environment variable values depends on Vixie Cron distributor and vintage; in
         non-error cases, behaviour described herein (removing quote pairs while possible)  agrees  with  Debian
         bookworm's.
         An  unpaired  outer-most  quote  (VAR=",  VAR="whatever"  ')  induces  a  parse  error  in Vixie Cron.
         systemd-crontab-generator(8), seeing no pairs, simply stops processing.
        systemd-cron since v1.16 (2023-07-10) but before  v2.6.0  (2025-09-11)  dequoted  values  by  stripping
         white-space  from both sides, then removing initial and terminal 's, then removing initial and terminal
         "s, then removing initial and terminal spaces (‘ ’s).  This naturally meant it was impossible to have a
         value with terminal or initial spaces.
         systemd-cron before v1.4.0 (2014-11-04) hadn't processed quotes at all, and  between  v1.4.0  and  1.16
         didn't run the space removal step.

DIAGNOSTICS

       You can see how your crontab was translated by running
             systemctl cat cron-username-*
       (though completion may be more convenient).

AUTHORS

       Paul  Vixie  <paul@vix.com>  is the author of his popular cron implementaton and original creator of this
       manual page.  This page has also been modified for Debian by Steve Greenland, Javier  Fernandez-Sanguino,
       and Christian Kastner.  This page has been reworded by Alexandre Detiste and further editorialised by наб
       <nabijaczleweli@nabijaczleweli.xyz> for inclusion in systemd-cron.

systemd-cron 2.6.0-1                               2025-09-10                                         CRONTAB(5)