For hcron v0.21. See here for all releases.
cron, the ubiquitous periodic scheduler, is one of the workhorses in the UNIX toolbox. There is no need to produce yet another cron ... unless it brings something new to the table. hcron does just that in a number of really useful and practical ways. For example:
hcron is enterprise-ready having proven itself over many years of use in development and operational environments, by hundreds of users, with tens of thousands of events being scheduled each day.
ssh to launch events across the network. As such, it requires that the user ssh configuration be set up to not require user interaction to run (e.g., no password, no passphrase, or yes/no responses).
This is done by setting the ssh key:
ssh-keygen cd ~/.ssh cat id_dsa.pub id_rsa.pub >> authorized_keys
and the ssh config file:
Host *.<domain> StrictHostKeyChecking no BatchMode yes
If full hostnames (i.e., which include the domain) are not used, then it may be necessary to add the following, too:
Host * StrictHostKeyChecking no BatchMode yes
If host keys change frequently, you may also benefit from:
For more, see man page for
All operations are carried out with:
hcron-conv- tool to convert between a
crontabfile and hcron event files
hcron-event- create and modify event files
hcron-info- show hcron-related information on the hcron scheduler machine; must be executed on the hcron scheduler machine
hcron-reload- generate snapshot of event files and trigger hcron scheduler to reload; must be executed on the hcron scheduler machine
hcron-run- Simulate scheduling of events
Each event is defined in its own file. An event file contains key=value lines, empty lines, or comment lines (starting with
hcron-event, an empty event file will be created as:
as_user= host= command= notify_email= notify_message= when_month= when_day= when_hour= when_minute= when_dow=
|(optional) username to use to when launching event. Must not require interaction.|
|Host on which to launch the |
|Command to run on the host (with minimal environment).|
|Email address to send notification to on successful launch.|
|Message in email when sent.|
|Month(s) the event should be scheduled. January is month 1.|
|Days of the month the event should be scheduled. The range is variable and depends on the month.|
|Hour (0-23) of the day the event should be scheduled.|
|Minute (0-59) of the hour the event should be scheduled.|
|Day (0-6) of the week the event should be scheduled. Sunday is day 0.|
when_* fields support the standard cron wildcard (*), ranges (e.g., 1-3), steps (e.g., 0-23/2), lists (e.g., 0,2,6,23).
|(optional) Event to execute if the event is not successfully launched.|
|(optional) Next event to execute if the event is successfully launched.|
|(optional) Subject in email when sent. hcron provides a default when not specified.|
|(optional) Event is ignored if the value matches the last component of the event name.|
|(optional) Year (2000-2050) the event should be scheduled. Default is |
Email reminder of weekly meeting on Mondays:
as_user= host=abc.xyz command=/bin/true notify_email=John.Smith@abc.xyz notify_message=Group meeting at 9am when_month=* when_day=* when_hour=0 when_minute=0 when_dow=1
Rotate logs daily at 00:05:
as_user= host=abc.xyz command=rotatelogs /var/log/syslog /var/log/messages notify_email= notify_message= when_month=* when_day=* when_hour=0 when_minute=5 when_dow=*
By default, the event command is executed in a minimal environment. To augment it, set environment variables or source profile scripts. E.g., for bash,
or, to have a full login environment loaded (highly discouraged):
Event files are organized in a event tree under the user home directory:
~/.hcron/ <hcronfqdn>/ events/ ...
<hcronfqdn> is the fully qualified host name of the machine running the hcron scheduler. Run "
hcron-info --fqdn" on the machine running the hcron-scheduler to get the correct value.
Make sure that the
Event files under
events/ should be given meaningful names and may be organized using directories. Directory names will be part of the full event name. If symlinks are used, they must reference only items under the same
events/ tree and use relative paths.
Rotate logs on 3 machines:
~/.hcron/hcron.xyz/events/ rotatelogs/ mach1.xyz mach2.xyz mach3.xyz
where the event files
rotatelogs/mach3.xyz use the event definition above but with the following modifications, respectively:
Depending on the configuration (see
names_to_ignore_regexp), some filenames may be ignored.
The default setting is:
." (hidden files; gvim temporary files)
~" (commonly used for emacs temporary files)
hcron supports variables for use in event files. Some variables are provided by the system, others are defined by the user. Some are substituted early while others late.
Early substitution means that they are substituted when the event is loaded. Late substitution is done just before the event is executed.
All variables are of string type. They are specified as
name=value and processed in order
When referencing variables, they must be prefixed by an operator:
$- value of (e.g.,
#- count of (e.g.,
All system variables start with the prefix
HCRON_ and is reserved.
Early substitution variables:
|The fully qualified hostname running the hcron scheduler.|
|The full event name relative to the |
Late substitution variables:
|Local date and time of the event activation. Format: |
|Same as |
|Colon-separated list of event names executed in an event chain by |
|Local date and time of the event schedule. Format: |
|Same as |
|Colon-separated list of consecutive chained events to self by |
The activation time is when the event is activated/executed. The schedule time is when the event is scheduled based on the
when_* settings. The two are the same except when hcron is behind schedule (for whatever reason), which is rare.
Given a string, splitting will return a list of items. Joining will put a list of items together giving a string.
The split and join operators are:
<split_sep>is the separator used to split the string
<join_sep>is the separator used to join the items
The default split and join separators are ":" if not specified; the join separator is the same as the split separator if not specified. The separators may be zero or more characters.
The only exception to this rule is when working with the
HCRON_EVENT_NAME variable for which "/" is the default separator.
H_LETTERS=a:b:c H_TENS=10_20_30_40 H_MACHS=mach1:mach2:mach3 H_DIGITS=1234
|"a", "b", "c"||a:b:c|
|"10", "20", "30", "40"||10_20_30_40|
|"mach1", "mach2", "mach3"||mach1:mach2:mach3|
|"10", "20", "30", "40"||10:20:30:40|
|"a", "b", "c"||a_b_c|
|"1", "2", "3", "4"||1-2-3-4|
A split operation is always accompanied by a join operation. Recall that variables are of string types only and so the intermediate "list" produced by a split operation is always joined.
Given the results of a split operation, the index operator can be used to extract items to be joined.
Indexing takes the forms:
When using indexing shorthand, if
<step> are not specified, the values default to 0, the number of elements, and 1, respectively, unless the step is negative in which case the
<end> values are reversed. See Python for more on indexing/slicing which is followed here.
Given the settings above:
|"a", "b", "c"||"b"||b|
|"a", "b", "c"||"a", "c"||a:c|
|"10", "20", "30", "40"||"10", "30"||10_30|
|"10", "20", "30", "40"||"40"||40|
|"1", "2", "3", "4"||"4", "3", "2", "1"||4-3-2-1|
Rather than using the value of a variable, the count can be obtained.
Give the settings above:
|"a", "b", "c"||"b"||1|
|"a", "b", "c"||"a", "c"||2|
|"10", "20", "30", "40"||"10", "30"||2|
|"10", "20", "30", "40"||"40"||1|
|"1", "2", "3", "4"||"4", "3", "2", "1"||4|
Other than what has already been described, operations cannot be combined such as:
but, instead, must be carried out with multiple steps:
In most cases, this is not much of an issue and will add only a few extra lines.
As the number of event files grows, it is sometimes helpful to be able to reuse the contents of an existing event file. This can be achieved using the include directive:
The include directive is resolved when the including event is loaded prior to early substitution.
Included event files need not be fully specified (they will be rejected if not). In fact, included files will often contain variable settings alone.
include /vars as_user=... host=... ...
H_X=hello H_Y=world as_user=... host=... ...
When many similar events must be defined and the differences can be handled using variables, a common event file, a template, can be used. A template is like any other event file except for the field
template_name. If, when hcron loads an event file, the
template_name field is set and its value matches the event file, hcron will recognize it as a template and ignore it. To use the template, symlinks are created which point to it.
Give the template file:
as_user= host=abc.xyz command=rotatelogs /var/log/$HCRON_EVENT_NAME[-1] notify_email= notify_message= when_month=* when_day=* when_hour=0 when_minute=5 when_dow=* template_name=template
we can set up some symlinks pointing to the template file:
.../events/ rotatelogs/ template auth.log -> template messages -> template syslog -> template
where three non-template events are defined (using only symlinks) with specialized
command settings so that
/var/log/syslog will be rotated. The
HCRON_EVENT_NAME is used to specialize the template to specify the log file in the
command field but could be used to set other fields, also.
When an event is scheduled, it becomes the first event in an event chain. If no other events are configured to be called afterward, then the chain remains with one event. Otherwise another event is called during the same scheduling period. Event chains are configured using
next_event (successful launch) and
failover_event (failed event launch), each of which can specify their own
The event chain is available in the
HCRON_EVENT_CHAIN variable, and the current event in
HCRON_SELF_EVENT. The maximum number of chained events is determined by the server configuration.
Given a set of event files:
.../events/ one two three fail
one should call
two which should call
fail only if the others failed to launch. The respective events files would be (snippets only):
and the failover event:
All actions taken by the hcron scheduler are logged (e.g., to
|Tag||Description and Format|
Alarm triggered because an execute operation has timed out.
Indicates that a
Discard user event information.
Server is exiting.
Load user events.
Sent email for event
Sleep time between subsequent work periods.
Server has started.
Statistics for work period.
When the scheduler loads an event tree snapshot, it writes the load status of each event to a file at
Reasons for a rejected event are:
hcron-info -es" to get this information.
Users are not allowed to use hcron by default. Instead, each user must be added to the
/etc/hcron/hcron.allow, one username per line. Comment lines must start with #.
All other scheduler configuration is done in the
/etc/hcron/hcron.conf file which takes the form of a Python dictionary. The keys of the configuration file are:
|Boolean indicating whether the local host may be targeted to run commands. The scheduler machine does not usually run commands in order to avoid overloading.|
|Boolean indicating whether events belonging to root will be run. Default is |
|Time (in seconds) allowed for a command to successfully spawn.|
|Base path for hcron events. Default is |
|Path to the log file. A relative path is anchored at |
|Maximum number of chained events allowed. Prevents against infinite recursion.|
|Maximum number of events a user may have.|
|Maximum size of the hcron event tree snapshot created at |
|Regular expression used to determine event names to ignore.|
|SMTP server to use for sending email notifications.|
|Delay between retry for obtaining information for |
|Number of retries to obtaining information for |
|Username used to test if credentials information is available/working.|
|Boolean indicating whether to use syslog or the log file.|