Difference between revisions of "Cron"

From ArchWiki
Jump to: navigation, search
m (Example with opensmtpd: use internal link)
m (Long cron job: rewrite a sentence for readability)
 
(99 intermediate revisions by 43 users not shown)
Line 1: Line 1:
 +
{{Lowercase title}}
 
[[Category:Daemons and system services]]
 
[[Category:Daemons and system services]]
 
[[de:Cron]]
 
[[de:Cron]]
 
[[fr:Cron]]
 
[[fr:Cron]]
 +
[[ja:Cron]]
 +
[[ko:Cron]]
 
[[sk:Cron]]
 
[[sk:Cron]]
 
[[zh-CN:Cron]]
 
[[zh-CN:Cron]]
{{Article summary start}}
+
[[ru:Cron]]
{{Article summary text|An overview of the standard task scheduling daemon on GNU/Linux systems.}}
+
{{Related articles start}}
{{Article summary heading|Resources}}
+
{{Related|systemd/Timers}}
{{Article summary link|Gentoo Linux Cron Guide|http://www.gentoo.org/doc/en/cron-guide.xml}}
+
{{Related|Update packages from crontab}}
{{Article summary end}}
+
{{Related articles end}}
{{Lowercase_title}}
+
  
From [https://en.wikipedia.org/wiki/Cron Wikipedia]:
+
From [[Wikipedia:Cron|Wikipedia]]:
  
'''''cron''' is the time-based job scheduler in Unix-like computer operating systems. cron enables users to schedule jobs (commands or shell scripts) to run periodically at certain times or dates. It is commonly used to automate system maintenance or administration [...]''
+
:''cron'' is the time-based job scheduler in Unix-like computer operating systems. cron enables users to schedule jobs (commands or shell scripts) to run periodically at certain times or dates. It is commonly used to automate system maintenance or administration.
  
 
== Installation ==
 
== Installation ==
  
{{Pkg|cronie}} is installed by default as part of the '''base''' group. Other cron implementations exist if preferred, Gentoo's [http://www.gentoo.org/doc/en/cron-guide.xml Cron Guide] offers comparisons. For example, {{Pkg|fcron}}, {{AUR|bcron}} or {{AUR|vixie-cron}} are other alternatives. {{AUR|dcron}} used to be the default cron implementation in Arch Linux until May 2011.
+
There are many cron implementations, but none of them are installed by default as the base system uses [[systemd/Timers]] instead. See the Gentoo's [http://www.gentoo.org/doc/en/cron-guide.xml cron guide], which offers comparisons.
 +
 
 +
Packages available:
 +
 
 +
* {{Pkg|cronie}}
 +
* {{Pkg|fcron}}
 +
* {{AUR|bcron}}{{Broken package link|{{aur-mirror|bcron}}}}
 +
* {{AUR|dcron}}
 +
* {{AUR|vixie-cron}}
 +
* {{AUR|scron-git}}
  
 
== Configuration ==
 
== Configuration ==
  
=== Users & autostart ===
+
=== Activation and autostart ===
  
cron should be working upon login on a new system to run root scripts. This can be check by looking at the log in {{ic|/var/log/}}. In order to use crontab application (editor for job entries), users must be members of a designated group {{ic|users}} or {{ic|root}}, of which all users should already be members. To ensure cron starts on boot, enable {{ic|cronie.service}} or {{ic|dcron.service}} with {{ic|systemctl enable <service_name>}} depending on which cron implementation you use.
+
After installation, the daemon will not be enabled by default. The installed package likely provides a service, which can be controlled by [[systemd#Using units|systemctl]]. For example, ''cronie'' uses {{ic|cronie.service}}.
 +
 
 +
Check {{ic|/etc/cron.daily/}} and similar directories to see which jobs are present. Activating cron service will trigger all of them.
 +
 
 +
{{Note|''cronie'' provides the {{ic|0anacron}} ''hourly'' job, which allows for [[#Asynchronous job processing|delayed runs of other jobs]] e.g. if the computer was switched off at the moment of standard execution.}}
  
 
=== Handling errors of jobs ===
 
=== Handling errors of jobs ===
  
cron registers the output from '''stdout''' and '''stderr''' and attempts to send it as email to the user's spools via the {{ic|sendmail}} command. Cronie disables mail output if {{ic|/usr/bin/sendmail}} is not found. To log these messages use the {{ic|-m}} option and write a script or install a rudimentary SMTP subsystem.
+
cron registers the output from ''stdout'' and ''stderr'' and attempts to send it as email to the user's spools via the {{ic|sendmail}} command. Cronie disables mail output if {{ic|/usr/bin/sendmail}} is not found. In order for mail to be written to a user's spool, there must be an smtp daemon running on the system, e.g. {{Pkg|opensmtpd}}. Otherwise, you can install a package that provides the sendmail command, and configure it to send mail to a remote mail exchanger. You can also log the messages by using the {{ic|-m}} option and writing a custom script.
  
# [[Systemd#Editing_provided_unit_files|Edit]] the {{ic|cronie.service}} unit.
+
# [[Systemd#Editing provided units|Edit]] the {{ic|cronie.service}} unit.
# Install {{Pkg|esmtp}}, {{Pkg|msmtp}}, {{Pkg|opensmtpd}} or write a custom script.
+
# Install {{Pkg|esmtp}}, [[msmtp]], {{Pkg|opensmtpd}} or write a custom script.
  
 
==== Example with msmtp ====
 
==== Example with msmtp ====
  
Here are two ways to obtain emails from cronie with msmtp:
+
{{Expansion|How exactly do I ''make sure it detects the new {{ic|sendmail}} command''?}}
 +
 
 +
Install {{Pkg|msmtp-mta}} which creates a symbolic link from {{ic|/usr/bin/sendmail}} to {{ic|/usr/bin/msmtp}}. Restart {{ic|cronie}} to make sure it detects the new {{ic|sendmail}} command. You must then provide a way for {{ic|msmtp}} to convert your username into an email address.
 +
 
 +
Then either add {{ic|MAILTO}} line to your crontab, like so:
 +
 
 +
<nowiki>MAILTO=your@email.com</nowiki>
 +
 
 +
'''or''' create {{ic|/etc/msmtprc}} and append this line:
 +
 
 +
aliases /etc/aliases
 +
 
 +
and create {{ic|/etc/aliases}}:
 +
 
 +
your_username: your@email.com
 +
# Optional:
 +
default: your@email.com
 +
 
 +
Then [[Systemd#Editing provided units|modify the configuration]] of ''cronie'' daemon by replacing the {{ic|ExecStart}} command with:
  
# Install the {{Pkg|msmtp-mta}} package which effectively creates a symbolic link from {{ic|/usr/bin/sendmail}} to {{ic|/usr/bin/msmtp}}. You must then provide a way for msmtp to convert your username into an email address.
+
ExecStart=/usr/bin/crond -n -m '/usr/bin/msmtp -t'
#*Either add a {{ic|MAILTO}} line to your crontab, like so:{{bc|<nowiki>MAILTO=your@email.com</nowiki>}}&mdash; OR &mdash;
+
#*add this line to {{ic|/etc/msmtprc}}:{{bc|aliases /etc/aliases}}and create {{ic|/etc/aliases}}:{{bc|your_username: your@email.com<br># Optional:<br>default: your@email.com}}
+
# [[Systemd#Editing_provided_unit_files|Edit]] the {{ic|cronie.service}} unit. For example, create {{ic|/etc/sytemd/system/cronie.service.d/msmtp.conf}}:{{bc|<nowiki>[Service]
+
ExecStart=
+
ExecStart=/usr/bin/crond -n -m '/usr/bin/msmtp -t'</nowiki>}}Note: the empty {{ic|<nowiki>ExecStart=</nowiki>}} cancels any previous {{ic|ExecStart}} commands.
+
  
 
==== Example with esmtp ====
 
==== Example with esmtp ====
  
# pacman -S esmtp procmail
+
Install {{Pkg|esmtp}} and {{Pkg|procmail}}.
  
 
After installation configure the routing:
 
After installation configure the routing:
Line 89: Line 117:
 
==== Example with opensmtpd ====
 
==== Example with opensmtpd ====
  
# pacman -S opensmtpd
+
Install {{Pkg|opensmtpd}}.
  
 
Edit {{ic|/etc/smtpd/smtpd.conf}}. The following configuration allows for local delivery:
 
Edit {{ic|/etc/smtpd/smtpd.conf}}. The following configuration allows for local delivery:
Line 96: Line 124:
 
  accept for local deliver to mbox
 
  accept for local deliver to mbox
  
You can proceed to test it:
+
You can proceed to test it. First [[start]] {{ic|smtpd.service}}. Then do:
# systemctl start smtpd
+
 
  $ echo test | sendmail user
 
  $ echo test | sendmail user
  
''user'' can check his/her mail in with any [[:Category:Email_Client|reader]] able to handle mbox format, or just have a look at the file {{ic|/var/spool/mail/''user''}}. If everything goes as expected, you can enable opensmtpd for future boots:
+
''user'' can check his/her mail in with any [[:Category:Email clients|reader]] able to handle mbox format, or just have a look at the file {{ic|/var/spool/mail/''user''}}. If everything goes as expected, you can [[enable]] opensmtpd for future boots.
# systemctl enable smtpd
+
  
This approach has the advantage of not sending local cron notifications to a remote server. Not even network connection is needed. On the downside, you need a new daemon running.
+
This approach has the advantage of not sending local cron notifications to a remote server. On the downside, you need a new daemon running.
  
{{Note|At the moment of writing the Arch opensmtpd package does not create all needed directories under {{ic|/var/spool/smtpd}}, but the daemon will warn about that specifying the required ownerships and permissions. Just create them as suggested.}}
+
{{Note|
 
+
* At the moment of writing the Arch opensmtpd package does not create all needed directories under {{ic|/var/spool/smtpd}}, but the daemon will warn about that specifying the required ownerships and permissions. Just create them as suggested.
{{Note|Even though the suggested configuration does not accept remote connections, it's a healthy precaution to add an additional layer of security blocking port 25 with [[iptables]] or similar.}}
+
* Even though the suggested configuration does not accept remote connections, it's a healthy precaution to add an additional layer of security blocking port 25 with [[iptables]] or similar.
 +
}}
  
 
==== Long cron job ====
 
==== Long cron job ====
Line 129: Line 156:
 
; sponge: sponge reads standard input and writes it out to the specified file. Unlike a shell redirect, sponge soaks up all its input before opening the output file… If no output file is specified, sponge outputs to stdout.
 
; sponge: sponge reads standard input and writes it out to the specified file. Unlike a shell redirect, sponge soaks up all its input before opening the output file… If no output file is specified, sponge outputs to stdout.
  
Even if it's not said chronic buffer the command output before opening its standard output (like sponge does).
+
Chronic too buffers the command output before opening its standard output.
  
 
== Crontab format ==
 
== Crontab format ==
Line 135: Line 162:
 
The basic format for a crontab is:
 
The basic format for a crontab is:
  
  <minute> <hour> <day_of_month> <month> <day_of_week> <command>
+
  ''minute'' ''hour'' ''day_of_month'' ''month'' ''day_of_week'' ''command''
  
 
* ''minute'' values can be from 0 to 59.
 
* ''minute'' values can be from 0 to 59.
Line 145: Line 172:
 
Multiple times may be specified with a comma, a range can be given with a hyphen, and the asterisk symbol is a wildcard character. Spaces are used to separate fields. For example, the line:
 
Multiple times may be specified with a comma, a range can be given with a hyphen, and the asterisk symbol is a wildcard character. Spaces are used to separate fields. For example, the line:
  
  *0,*5 9-16 * 1-5,9-12 1-5 ~/bin/i_love_cron.sh
+
  */5 9-16 * 1-5,9-12 1-5 ~/bin/i_love_cron.sh
  
Will execute the script {{Ic|i_love_cron.sh}} at five minute intervals from 9 AM to 4:55 PM on weekdays except during the summer months (June, July, and August). More examples and advanced configuration techniques can be found below.
+
Will execute the script {{ic|i_love_cron.sh}} at five minute intervals from 9 AM to 4:55 PM on weekdays except during the summer months (June, July, and August). More examples and advanced configuration techniques can be found below.
 +
 
 +
Besides, crontab has some special keywords:
 +
 
 +
@reboot at startup
 +
@yearly once a year
 +
@annually ( == @yearly)
 +
@monthly once a month
 +
@weekly once a week
 +
@daily once a day
 +
@midnight ( == @daily)
 +
@hourly once an hour
 +
 
 +
For example:
 +
 
 +
@reboot ~/bin/i_love_cron.sh
 +
 
 +
Will execute the script {{ic|i_love_cron.sh}} at startup.
 +
 
 +
See more at: http://www.linuxandlife.com/2013/01/how-to-use-crontab-to-schedule-tasks.html#sthash.AXvOdsAz.dpuf
  
 
== Basic commands ==
 
== Basic commands ==
Line 160: Line 206:
  
 
  $ crontab -e
 
  $ crontab -e
 +
 +
{{Note|By default the {{ic|crontab}} command uses the {{ic|vi}} editor. To change it, [[environment variable|export]] {{ic|EDITOR}} or {{ic|VISUAL}}, or specify the editor directly: {{ic|1=EDITOR=vim crontab -e}}.}}
  
 
To remove their crontabs, they should use:
 
To remove their crontabs, they should use:
Line 178: Line 226:
  
 
This same format (appending {{ic|-u ''username''}} to a command) works for listing and deleting crontabs as well.
 
This same format (appending {{ic|-u ''username''}} to a command) works for listing and deleting crontabs as well.
 
To use [[nano]] rather than [[vi]] as crontab editor, add the following lines to your shell's initialization file (eg. {{ic|/etc/profile}} or {{ic|/etc/bash.bashrc}}):
 
 
export EDITOR="/usr/bin/nano"
 
 
And restart open shells.
 
  
 
== Examples ==
 
== Examples ==
Line 191: Line 233:
 
  01 * * * * /bin/echo Hello, world!
 
  01 * * * * /bin/echo Hello, world!
  
runs the command {{Ic|/bin/echo Hello, world!}} on the first minute of every hour of every day of every month (i.e. at 12:01, 1:01, 2:01, etc.)
+
runs the command {{ic|/bin/echo Hello, world!}} on the first minute of every hour of every day of every month (i.e. at 12:01, 1:01, 2:01, etc.).
  
Similarly,
+
Similarly:
  
 
  */5 * * jan mon-fri /bin/echo Hello, world!
 
  */5 * * jan mon-fri /bin/echo Hello, world!
  
runs the same job every five minutes on weekdays during the month of January (i.e. at 12:00, 12:05, 12:10, etc.)
+
runs the same job every five minutes on weekdays during the month of January (i.e. at 12:00, 12:05, 12:10, etc.).
  
As noted in the ''Crontab Format'' section, the line:
+
The line (as noted in "man 5 crontab"):
  
 
  *0,*5 9-16 * 1-5,9-12 1-5 /home/user/bin/i_love_cron.sh
 
  *0,*5 9-16 * 1-5,9-12 1-5 /home/user/bin/i_love_cron.sh
  
Will execute the script {{Ic|i_love_cron.sh}} at five minute intervals from 9 AM to 5 PM (excluding 5 PM itself) every weekday (Mon-Fri) of every month except during the summer (June, July, and August).
+
will execute the script {{Ic|i_love_cron.sh}} at five minute intervals from 9 AM to 5 PM (excluding 5 PM itself) every weekday (Mon-Fri) of every month except during the summer (June, July, and August).
  
== More information ==
+
Periodical settings can also be entered as in this crontab template:
  
The cron daemon parses a configuration file known as {{ic|crontab}}. Each user on the system can maintain a separate crontab file to schedule commands individually. The root user's crontab is used to schedule system-wide tasks (though users may opt to use {{ic|/etc/crontab}} or the {{ic|/etc/cron.d}} directory, depending on which cron implementation they choose).
+
<pre># Chronological table of program loadings                                     
 +
# Edit with "crontab" for proper functionality, "man 5 crontab" for formatting
 +
# User: johndoe
  
There are slight differences between the crontab formats of the different cron daemons. The default root crontab for dcron looks like this:
+
# mm  hh  DD  MM  W /path/progam [--option]...  ( W = weekday: 0-6 [Sun=0] )
 +
  21  01  *  *  * /usr/bin/systemctl hibernate
 +
  @weekly          $HOME/.local/bin/trash-empty
 +
</pre>
  
{{hc|/var/spool/cron/root
+
== Default editor ==
|2=<nowiki>
+
# root crontab
+
# DO NOT EDIT THIS FILE MANUALLY! USE crontab -e INSTEAD
+
  
# man 1 crontab for acceptable formats:
+
To use an alternate default editor, define the {{ic|EDITOR}} environment variable in a shell initialization script as described in [[Environment variables]].
#    <minute> <hour> <day> <month> <dow> <tags and command>
+
#    <@freq> <tags and command>
+
  
# SYSTEM DAILY/WEEKLY/... FOLDERS
+
As a regular user, {{ic|su}} will need to be used instead of {{ic|sudo}} for the environment variable to be pulled correctly:
@hourly        ID=sys-hourly  /usr/sbin/run-cron /etc/cron.hourly
+
@daily          ID=sys-daily    /usr/sbin/run-cron /etc/cron.daily
+
@weekly        ID=sys-weekly  /usr/sbin/run-cron /etc/cron.weekly
+
@monthly        ID=sys-monthly  /usr/sbin/run-cron /etc/cron.monthly
+
</nowiki>}}
+
  
These lines exemplify one of the formats that crontab entries can have, namely whitespace-separated fields specifying:
+
$ su -c "crontab -e"
  
# @period
+
To have an alias to this {{ic|printf}} is required to carry the arbitrary string because {{ic|su}} launches in a new shell:
# ID=jobname (this tag is specific to dcron)
+
# command
+
  
The other standard format for crontab entries is:
+
alias scron="su -c $(printf "%q " "crontab -e")"
 
+
# minute
+
# hour
+
# day
+
# month
+
# day of week
+
# command
+
 
+
The crontab files themselves are usually stored as {{ic|/var/spool/cron/username}}. For example, root's crontab is found at {{ic|/var/spool/cron/root}}
+
 
+
See the crontab [[man page]] for further information and configuration examples.
+
  
 
== run-parts issue ==
 
== run-parts issue ==
Line 250: Line 274:
 
cronie uses {{ic|run-parts}} to carry out script in {{ic|cron.daily}}/{{ic|cron.weekly}}/{{ic|cron.monthly}}. Be careful that the script name in these won't include a dot (.), e.g. {{ic|backup.sh}}, since {{ic|run-parts}} without options will ignore them (see: {{ic|man run-parts}}).
 
cronie uses {{ic|run-parts}} to carry out script in {{ic|cron.daily}}/{{ic|cron.weekly}}/{{ic|cron.monthly}}. Be careful that the script name in these won't include a dot (.), e.g. {{ic|backup.sh}}, since {{ic|run-parts}} without options will ignore them (see: {{ic|man run-parts}}).
  
== Running Xorg server based applications ==
+
== Running X.org server-based applications ==
  
If you find that you can't run X apps from cron jobs then use this prefix:
+
Cron does not run under the X.org server therefore it cannot know the environmental variable necessary to be able to start an X.org server application so they will have to be defined. One can use a program like {{AUR|xuserrun}}{{Broken package link|{{aur-mirror|xuserrun}}}} to do it:
  
  export DISPLAY=:0.0 ;
+
  17 02 * ... /usr/bin/xuserrun /usr/bin/xclock
  
This sets the {{ic|DISPLAY}} variable to the first display, which is usually right
+
Or then can be defined manually ({{ic|echo $DISPLAY}} will give the current DISPLAY value):
unless you run multiple X servers on your machine.
+
  
If it still doesn't work, then you need to use {{ic|xhost}} to give your user control
+
17 02 * ... env DISPLAY=:0 /usr/bin/xclock
over X:
+
 
 +
If done through say SSH, permission will need be given:
  
 
  # xhost +si:localuser:$(whoami)
 
  # xhost +si:localuser:$(whoami)
Line 268: Line 292:
 
If you regularly turn off your computer but do not want to miss jobs, there are some solutions available (easiest to hardest):
 
If you regularly turn off your computer but do not want to miss jobs, there are some solutions available (easiest to hardest):
  
===Dcron===
+
=== Cronie ===
Vanilla dcron supports asynchronous job processing. Just put it with @hourly, @daily, @weekly or @monthly with a jobname, like this:
+
{{Pkg|cronie}} comes with anacron included.
 +
The project homepage reads:
 +
 
 +
Cronie contains the standard UNIX daemon crond that runs specified programs at scheduled times and related tools.
 +
It is based on the original cron and has security and configuration enhancements like the ability to use pam and SELinux.
 +
 
 +
=== Dcron ===
 +
 
 +
Vanilla {{AUR|dcron}} supports asynchronous job processing. Just put it with @hourly, @daily, @weekly or @monthly with a jobname, like this:
  
 
  @hourly        ID=greatest_ever_job      echo This job is very useful.
 
  @hourly        ID=greatest_ever_job      echo This job is very useful.
  
===Cronwhip===
+
=== Cronwhip ===
([https://aur.archlinux.org/packages.php?ID=21079 AUR], [https://bbs.archlinux.org/viewtopic.php?id=57973 forum thread]): Script to automatically run missed cron jobs; works with the former default cron implementation, dcron.
+
  
===Anacron===
+
{{AUR|cronwhip}} is a script to automatically run missed cron jobs; it works with the former default cron implementation, ''dcron''.
([https://aur.archlinux.org/packages.php?ID=5196 AUR]): Full replacement for dcron, processes jobs asynchronously.
+
See also the [https://bbs.archlinux.org/viewtopic.php?id=57973 forum thread].
  
===Fcron===
+
=== Anacron ===
([https://www.archlinux.org/packages/community/i686/fcron/ Community], [https://bbs.archlinux.org/viewtopic.php?id=140497 forum thread]): Like anacron, fcron assumes the computer is not always running and, unlike anacron, it can schedule events at intervals shorter than a single day. Like cronwhip, it can run jobs that should have been run during the computer's downtime.
+
Anacron is a full replacement for ''dcron'' which processes jobs asynchronously.
 +
 
 +
It is provided by {{Pkg|cronie}}. The configuration file is {{ic|/etc/anacrontab}}. Information on the format can be found in the {{ic|anacrontab(5)}} [[man page]]. Running {{ic|anacron -T}} will test {{ic|/etc/anacrontab}} for validity.
 +
 
 +
=== Fcron ===
 +
 
 +
Like ''anacron'', {{Pkg|fcron}} assumes the computer is not always running and, unlike ''anacron'', it can schedule events at intervals shorter than a single day which may be useful for systems which suspend/hibernate regularly (such as a laptop). Like cronwhip, fcron can run jobs that should have been run during the computer's downtime.
 +
 
 +
When replacing {{Pkg|cronie}} with fcron be aware the spool directory is {{ic|/var/spool/fcron}} and the {{ic|fcrontab}} command is used instead of ''crontab'' to edit the user crontabs. These crontabs are stored in a binary format with the text version next to them as ''foo''.orig in the spool directory. Any scripts which manually edit user crontabs may need to be adjusted due to this difference in behavior.
 +
 
 +
A quick scriptlet which may aide in converting traditional user crontabs to fcron format:
 +
 
 +
{{bc|
 +
cd /var/spool/cron && (
 +
for ctab in *; do
 +
  fcrontab ${ctab} -u ${ctab}
 +
done
 +
)
 +
}}
 +
 
 +
See also the [https://bbs.archlinux.org/viewtopic.php?id=140497 forum thread].
  
 
== Ensuring exclusivity ==
 
== Ensuring exclusivity ==
  
If you run potentially long-running jobs (e.g., a backup might all of a sudden run for a long time, because of many changes or a particular slow network connection), then {{AUR|lockrun}} can ensure that the cron job won't start a second time.
+
If you run potentially long-running jobs (e.g., a backup might all of a sudden run for a long time, because of many changes or a particular slow network connection), then {{ic|flock}} ({{Pkg|util-linux}}) can ensure that the cron job won't start a second time.
 +
 
 +
  5,35 * * * * /usr/bin/flock -n /tmp/lock.backup /root/make-backup.sh
 +
 
 +
== cronie ==
 +
 
 +
Long time users of vixie-cron (traditional cron) will be confused by how cronie is set up.  Here is the relevant file hierarchy:
 +
 
 +
    /etc
 +
      |----- anacrontab
 +
      |----- cron.d
 +
              | ----- 0hourly
 +
      |----- cron.daily
 +
      |----- cron.deny
 +
      |----- cron.hourly
 +
      |----- cron.monthly
 +
      |----- cron.weekly
 +
      |----- crontab
 +
 
 +
 
 +
Note that the crontab file is '''not''' created by default, but jobs added here will be run if you wish to use this file.  Cronie provides both cron and anacron functionality.  The difference is that cron will run jobs at particular time intervals (down to a granularity of one minute) ''if the machine is on at the particular time specified'', while anacron runs jobs (with a minimum daily granularity) without assuming that the machine is turned on all the time.  When the machine is on, anacron will check to see if there are any jobs that ''should have been run'' and will run them accordingly.  The {{ic|/etc/cron.d}} and {{ic|/etc/cron.hourly}} directories are associated with '''cron''' functionality, while the {{ic|/etc/anacrontab}} file and {{ic|/etc/cron.daily}}, {{ic|/etc/cron.weekly}}, and {{ic|/etc/cron.monthly}} directories are associated with '''anacron''' functionality.  The {{ic|/etc/cron.deny}} file is there so that any user who is not specifically prohibited can create their own cron jobs.
 +
 
 +
To implement a system-wide cron job, create a crontab-like file for it and place it in the {{ic|/etc/cron.d}} directory or add the job to /etc/crontab.  Any executable (these are almost always shell scripts) in
 +
{{ic|/etc/cron.hourly}} will be run every hour.
 +
 
 +
Anacron functionality is implemented similarly, however using the {{ic|/etc/cron.daily}}, {{ic|/etc/cron.weekly}}, or {{ic|/etc/cron.monthly}} directories, depending on how frequently you want the job to be run.  The anacron job files are also executables; i.e. not in crontab-format. Anacron is triggered at the beginning of every hour by the crontab file {{ic|/etc/cron.d/0hourly}} which runs the executables in {{ic|/etc/cron.hourly}} including the file {{ic|/etc/cron.hourly/0anacron}} - deleting these will prevent anacron running any daily, weekly or monthly tasks.
 +
 
 +
{{Note|the output of {{ic|systemctl status cronie}} might show a message such as {{ic|crond[<PID>]: (root) CAN'T OPEN (/etc/crontab): No such file or directory}}. However, this is not an error as of cronie 1.4.8. See [https://lists.archlinux.org/pipermail/arch-general/2012-February/025178.html this] discussion.}}
 +
 
 +
== Dcron ==
 +
 
 +
The cron daemon parses a configuration file known as {{ic|crontab}}. Each user on the system can maintain a separate crontab file to schedule commands individually. The root user's crontab is used to schedule system-wide tasks (though users may opt to use {{ic|/etc/crontab}} or the {{ic|/etc/cron.d}} directory, depending on which cron implementation they choose).
 +
 
 +
{{hc|/var/spool/cron/root
 +
|2=<nowiki>
 +
# Run command at a scheduled time
 +
# Edit this 'crontab -e' for error checking, man 1 crontab for acceptable format
 +
 
 +
# <@freq>                      <tags and command>
 +
@hourly        ID=sys-hourly  /usr/sbin/run-cron /etc/cron.hourly
 +
@daily          ID=sys-daily    /usr/sbin/run-cron /etc/cron.daily
 +
@weekly        ID=sys-weekly  /usr/sbin/run-cron /etc/cron.weekly
 +
@monthly        ID=sys-monthly  /usr/sbin/run-cron /etc/cron.monthly
 +
 
 +
# mm  hh  DD  MM  W /path/command (or tags) # W = week: 0-6, Sun=0
 +
  21  01  *  *  * /usr/bin/systemctl suspend
 +
</nowiki>}}
 +
 
 +
These lines exemplify one of the formats that crontab entries can have, namely whitespace-separated fields specifying:
 +
 
 +
# @period
 +
# ID=jobname (this tag is specific to dcron)
 +
# command
 +
 
 +
The other standard format for crontab entries is:
 +
 
 +
# minute
 +
# hour
 +
# day
 +
# month
 +
# day of week
 +
# command
 +
 
 +
The crontab files themselves are usually stored as {{ic|/var/spool/cron/username}}. For example, root's crontab is found at {{ic|/var/spool/cron/root}}
 +
 
 +
See the crontab [[man page]] for further information and configuration examples.
  
  5,35 * * * * /usr/bin/lockrun -n /tmp/lock.backup /root/make-backup.sh
+
== See also ==
  
== See Also ==
+
* [http://www.gentoo.org/doc/en/cron-guide.xml Gentoo Linux Cron Guide]
* [http://gotux.net/arch-linux/crontab-usage/ CronTab Usage Tutorial]
+

Latest revision as of 09:08, 13 May 2016

From Wikipedia:

cron is the time-based job scheduler in Unix-like computer operating systems. cron enables users to schedule jobs (commands or shell scripts) to run periodically at certain times or dates. It is commonly used to automate system maintenance or administration.

Installation

There are many cron implementations, but none of them are installed by default as the base system uses systemd/Timers instead. See the Gentoo's cron guide, which offers comparisons.

Packages available:

Configuration

Activation and autostart

After installation, the daemon will not be enabled by default. The installed package likely provides a service, which can be controlled by systemctl. For example, cronie uses cronie.service.

Check /etc/cron.daily/ and similar directories to see which jobs are present. Activating cron service will trigger all of them.

Note: cronie provides the 0anacron hourly job, which allows for delayed runs of other jobs e.g. if the computer was switched off at the moment of standard execution.

Handling errors of jobs

cron registers the output from stdout and stderr and attempts to send it as email to the user's spools via the sendmail command. Cronie disables mail output if /usr/bin/sendmail is not found. In order for mail to be written to a user's spool, there must be an smtp daemon running on the system, e.g. opensmtpd. Otherwise, you can install a package that provides the sendmail command, and configure it to send mail to a remote mail exchanger. You can also log the messages by using the -m option and writing a custom script.

  1. Edit the cronie.service unit.
  2. Install esmtp, msmtp, opensmtpd or write a custom script.

Example with msmtp

Tango-view-fullscreen.pngThis article or section needs expansion.Tango-view-fullscreen.png

Reason: How exactly do I make sure it detects the new sendmail command? (Discuss in Talk:Cron#)

Install msmtp-mta which creates a symbolic link from /usr/bin/sendmail to /usr/bin/msmtp. Restart cronie to make sure it detects the new sendmail command. You must then provide a way for msmtp to convert your username into an email address.

Then either add MAILTO line to your crontab, like so:

MAILTO=your@email.com

or create /etc/msmtprc and append this line:

aliases /etc/aliases

and create /etc/aliases:

your_username: your@email.com
# Optional:
default: your@email.com

Then modify the configuration of cronie daemon by replacing the ExecStart command with:

ExecStart=/usr/bin/crond -n -m '/usr/bin/msmtp -t'

Example with esmtp

Install esmtp and procmail.

After installation configure the routing:

/etc/esmtprc
identity myself@myisp.com
       hostname mail.myisp.com:25
       username "myself"
       password "secret"
       starttls enabled
       default
mda "/usr/bin/procmail -d %T"

Procmail needs root privileges to work in delivery mode but it is not an issue if you are running the cronjobs as root anyway.

To test that everything works correctly, create a file message.txt with "test message" in it.

From the same directory run:

$ sendmail user_name < message.txt 

then:

$ cat /var/spool/mail/user_name

You should now see the test message and the time and date it was sent.

The error output of all jobs will now be redirected to /var/spool/mail/user_name.

Due to the privileged issue, it is hard to create and send emails to root (e.g. su -c ""). You can ask esmtp to forward all root's email to an ordinary user with:

/etc/esmtprc
force_mda="user-name"
Note: If the above test didn't work, you may try creating a local configuration in ~/.esmtprc with the same content.

Run the following command to make sure it has the correct permission:

$ chmod 710 ~/.esmtprc
Then repeat the test with message.txt exactly as before.

Example with opensmtpd

Install opensmtpd.

Edit /etc/smtpd/smtpd.conf. The following configuration allows for local delivery:

listen on localhost
accept for local deliver to mbox

You can proceed to test it. First start smtpd.service. Then do:

$ echo test | sendmail user

user can check his/her mail in with any reader able to handle mbox format, or just have a look at the file /var/spool/mail/user. If everything goes as expected, you can enable opensmtpd for future boots.

This approach has the advantage of not sending local cron notifications to a remote server. On the downside, you need a new daemon running.

Note:
  • At the moment of writing the Arch opensmtpd package does not create all needed directories under /var/spool/smtpd, but the daemon will warn about that specifying the required ownerships and permissions. Just create them as suggested.
  • Even though the suggested configuration does not accept remote connections, it's a healthy precaution to add an additional layer of security blocking port 25 with iptables or similar.

Long cron job

Suppose this program is invoked by cron :

#!/bin/sh
echo "I had a recoverable error!"
sleep 1h

What happens is this:

  1. cron runs the script
  2. as soon as cron sees some output, it runs your MTA, and provides it with the headers. It leaves the pipe open, because the job hasn't finished and there might be more output.
  3. the MTA opens the connection to postfix and leaves that connection open while it waits for the rest of the body.
  4. postfix closes the idle connection after less than an hour and you get an error like this :
smtpmsg='421 … Error: timeout exceeded' errormsg='the server did not accept the mail'

To solve this problem you can use the command chronic or sponge from moreutils. From their respective man page:

chronic
chronic runs a command, and arranges for its standard out and standard error to only be displayed if the command fails (exits nonzero or crashes). If the command succeeds, any extraneous output will be hidden.
sponge
sponge reads standard input and writes it out to the specified file. Unlike a shell redirect, sponge soaks up all its input before opening the output file… If no output file is specified, sponge outputs to stdout.

Chronic too buffers the command output before opening its standard output.

Crontab format

The basic format for a crontab is:

minute hour day_of_month month day_of_week command
  • minute values can be from 0 to 59.
  • hour values can be from 0 to 23.
  • day_of_month values can be from 1 to 31.
  • month values can be from 1 to 12.
  • day_of_week values can be from 0 to 6, with 0 denoting Sunday.

Multiple times may be specified with a comma, a range can be given with a hyphen, and the asterisk symbol is a wildcard character. Spaces are used to separate fields. For example, the line:

*/5 9-16 * 1-5,9-12 1-5 ~/bin/i_love_cron.sh

Will execute the script i_love_cron.sh at five minute intervals from 9 AM to 4:55 PM on weekdays except during the summer months (June, July, and August). More examples and advanced configuration techniques can be found below.

Besides, crontab has some special keywords:

@reboot at startup 
@yearly once a year
@annually ( == @yearly)
@monthly once a month
@weekly once a week
@daily once a day
@midnight ( == @daily)
@hourly once an hour

For example:

@reboot ~/bin/i_love_cron.sh

Will execute the script i_love_cron.sh at startup.

See more at: http://www.linuxandlife.com/2013/01/how-to-use-crontab-to-schedule-tasks.html#sthash.AXvOdsAz.dpuf

Basic commands

Crontabs should never be edited directly; instead, users should use the crontab program to work with their crontabs. To be granted access to this command, user must be a member of the users group (see the gpasswd command).

To view their crontabs, users should issue the command:

$ crontab -l

To edit their crontabs, they may use:

$ crontab -e
Note: By default the crontab command uses the vi editor. To change it, export EDITOR or VISUAL, or specify the editor directly: EDITOR=vim crontab -e.

To remove their crontabs, they should use:

$ crontab -r

If a user has a saved crontab and would like to completely overwrite their old crontab, he or she should use:

$ crontab saved_crontab_filename

To overwrite a crontab from the command line (Wikipedia:stdin), use

$ crontab - 

To edit somebody else's crontab, issue the following command as root:

# crontab -u username -e

This same format (appending -u username to a command) works for listing and deleting crontabs as well.

Examples

The entry:

01 * * * * /bin/echo Hello, world!

runs the command /bin/echo Hello, world! on the first minute of every hour of every day of every month (i.e. at 12:01, 1:01, 2:01, etc.).

Similarly:

*/5 * * jan mon-fri /bin/echo Hello, world!

runs the same job every five minutes on weekdays during the month of January (i.e. at 12:00, 12:05, 12:10, etc.).

The line (as noted in "man 5 crontab"):

*0,*5 9-16 * 1-5,9-12 1-5 /home/user/bin/i_love_cron.sh

will execute the script i_love_cron.sh at five minute intervals from 9 AM to 5 PM (excluding 5 PM itself) every weekday (Mon-Fri) of every month except during the summer (June, July, and August).

Periodical settings can also be entered as in this crontab template:

# Chronological table of program loadings                                       
# Edit with "crontab" for proper functionality, "man 5 crontab" for formatting
# User: johndoe

# mm  hh  DD  MM  W /path/progam [--option]...  ( W = weekday: 0-6 [Sun=0] )
  21  01  *   *   * /usr/bin/systemctl hibernate
  @weekly           $HOME/.local/bin/trash-empty

Default editor

To use an alternate default editor, define the EDITOR environment variable in a shell initialization script as described in Environment variables.

As a regular user, su will need to be used instead of sudo for the environment variable to be pulled correctly:

$ su -c "crontab -e"

To have an alias to this printf is required to carry the arbitrary string because su launches in a new shell:

alias scron="su -c $(printf "%q " "crontab -e")"

run-parts issue

cronie uses run-parts to carry out script in cron.daily/cron.weekly/cron.monthly. Be careful that the script name in these won't include a dot (.), e.g. backup.sh, since run-parts without options will ignore them (see: man run-parts).

Running X.org server-based applications

Cron does not run under the X.org server therefore it cannot know the environmental variable necessary to be able to start an X.org server application so they will have to be defined. One can use a program like xuserrunAUR[broken link: archived in aur-mirror] to do it:

17 02 * ... /usr/bin/xuserrun /usr/bin/xclock

Or then can be defined manually (echo $DISPLAY will give the current DISPLAY value):

17 02 * ... env DISPLAY=:0 /usr/bin/xclock

If done through say SSH, permission will need be given:

# xhost +si:localuser:$(whoami)

Asynchronous job processing

If you regularly turn off your computer but do not want to miss jobs, there are some solutions available (easiest to hardest):

Cronie

cronie comes with anacron included. The project homepage reads:

Cronie contains the standard UNIX daemon crond that runs specified programs at scheduled times and related tools. It is based on the original cron and has security and configuration enhancements like the ability to use pam and SELinux.

Dcron

Vanilla dcronAUR supports asynchronous job processing. Just put it with @hourly, @daily, @weekly or @monthly with a jobname, like this:

@hourly         ID=greatest_ever_job      echo This job is very useful.

Cronwhip

cronwhipAUR is a script to automatically run missed cron jobs; it works with the former default cron implementation, dcron. See also the forum thread.

Anacron

Anacron is a full replacement for dcron which processes jobs asynchronously.

It is provided by cronie. The configuration file is /etc/anacrontab. Information on the format can be found in the anacrontab(5) man page. Running anacron -T will test /etc/anacrontab for validity.

Fcron

Like anacron, fcron assumes the computer is not always running and, unlike anacron, it can schedule events at intervals shorter than a single day which may be useful for systems which suspend/hibernate regularly (such as a laptop). Like cronwhip, fcron can run jobs that should have been run during the computer's downtime.

When replacing cronie with fcron be aware the spool directory is /var/spool/fcron and the fcrontab command is used instead of crontab to edit the user crontabs. These crontabs are stored in a binary format with the text version next to them as foo.orig in the spool directory. Any scripts which manually edit user crontabs may need to be adjusted due to this difference in behavior.

A quick scriptlet which may aide in converting traditional user crontabs to fcron format:

cd /var/spool/cron && (
 for ctab in *; do
  fcrontab ${ctab} -u ${ctab}
 done
)

See also the forum thread.

Ensuring exclusivity

If you run potentially long-running jobs (e.g., a backup might all of a sudden run for a long time, because of many changes or a particular slow network connection), then flock (util-linux) can ensure that the cron job won't start a second time.

  5,35 * * * * /usr/bin/flock -n /tmp/lock.backup /root/make-backup.sh

cronie

Long time users of vixie-cron (traditional cron) will be confused by how cronie is set up. Here is the relevant file hierarchy:

   /etc
     |----- anacrontab
     |----- cron.d
              | ----- 0hourly
     |----- cron.daily
     |----- cron.deny
     |----- cron.hourly
     |----- cron.monthly
     |----- cron.weekly
     |----- crontab


Note that the crontab file is not created by default, but jobs added here will be run if you wish to use this file. Cronie provides both cron and anacron functionality. The difference is that cron will run jobs at particular time intervals (down to a granularity of one minute) if the machine is on at the particular time specified, while anacron runs jobs (with a minimum daily granularity) without assuming that the machine is turned on all the time. When the machine is on, anacron will check to see if there are any jobs that should have been run and will run them accordingly. The /etc/cron.d and /etc/cron.hourly directories are associated with cron functionality, while the /etc/anacrontab file and /etc/cron.daily, /etc/cron.weekly, and /etc/cron.monthly directories are associated with anacron functionality. The /etc/cron.deny file is there so that any user who is not specifically prohibited can create their own cron jobs.

To implement a system-wide cron job, create a crontab-like file for it and place it in the /etc/cron.d directory or add the job to /etc/crontab. Any executable (these are almost always shell scripts) in /etc/cron.hourly will be run every hour.

Anacron functionality is implemented similarly, however using the /etc/cron.daily, /etc/cron.weekly, or /etc/cron.monthly directories, depending on how frequently you want the job to be run. The anacron job files are also executables; i.e. not in crontab-format. Anacron is triggered at the beginning of every hour by the crontab file /etc/cron.d/0hourly which runs the executables in /etc/cron.hourly including the file /etc/cron.hourly/0anacron - deleting these will prevent anacron running any daily, weekly or monthly tasks.

Note: the output of systemctl status cronie might show a message such as crond[<PID>]: (root) CAN'T OPEN (/etc/crontab): No such file or directory. However, this is not an error as of cronie 1.4.8. See this discussion.

Dcron

The cron daemon parses a configuration file known as crontab. Each user on the system can maintain a separate crontab file to schedule commands individually. The root user's crontab is used to schedule system-wide tasks (though users may opt to use /etc/crontab or the /etc/cron.d directory, depending on which cron implementation they choose).

/var/spool/cron/root
# Run command at a scheduled time
# Edit this 'crontab -e' for error checking, man 1 crontab for acceptable format

# <@freq>                       <tags and command>
@hourly         ID=sys-hourly   /usr/sbin/run-cron /etc/cron.hourly
@daily          ID=sys-daily    /usr/sbin/run-cron /etc/cron.daily
@weekly         ID=sys-weekly   /usr/sbin/run-cron /etc/cron.weekly
@monthly        ID=sys-monthly  /usr/sbin/run-cron /etc/cron.monthly

# mm  hh  DD  MM  W /path/command (or tags) # W = week: 0-6, Sun=0
  21  01  *   *   * /usr/bin/systemctl suspend

These lines exemplify one of the formats that crontab entries can have, namely whitespace-separated fields specifying:

  1. @period
  2. ID=jobname (this tag is specific to dcron)
  3. command

The other standard format for crontab entries is:

  1. minute
  2. hour
  3. day
  4. month
  5. day of week
  6. command

The crontab files themselves are usually stored as /var/spool/cron/username. For example, root's crontab is found at /var/spool/cron/root

See the crontab man page for further information and configuration examples.

See also