This feature has already been implemented in systemd (ver >= 212) using the Persistent=
directive so you just need to insert Persistent=true
in the unit file while using OnCalendar=
directive to establish the date/time to run the job.
Persistent=
Takes a boolean argument. If true, the time when the service unit was last triggered is stored on disk. When the timer is activated, the service unit is triggered immediately if it would have been triggered at least once during the time when the timer was inactive. This is useful to catch up on missed runs of the service when the machine was off. Note that this setting only has an effect on timers configured with OnCalendar=.
Digital Unix v4 (aka OSF1) implemented this (archived man page here):
You can specify the days on which the command is to execute in two fields
(day of the month and day of the week). You can specify both fields, or
you can specify only one field. To use only one field to specify the days,
the other field should contain an asterisk (*). If both methods are used,
the command is executed whenever either of the specifications is met.
And so does Solaris proper, though the text of the man page lacks clarity (and has done since forever), Example 3 is clear on the intended behaviour:
Example 3 Specifying Days of the Month and Week
This example runs a command on the first and fifteenth of each month, as well as on every Monday:
0 0 1,15 * 1
Dillon crond
interprets * * 2 * mon
to mean "the 2nd Monday of the month", which while useful, is also non-standard.
The answers in the question linked by @thanasisp are useful to read at this point. The "or" behaviour is from System V R2 (ca. 1985) at least.
I have found that when reading the Open Group documentation one needs to be aware of
- pedantic meaning of certain words in certain contexts, just like RFCs, but more so
- sections of text bounded by ⌦ ... ⌫ symbols (an unusual convention as these symbols are forward- and backward-delete)
There is text within the crontab reference marked [UP] ⌦ ... ⌫
which indicates optional behaviour (for crontab -e
) on the part of User Portable Utilies, the "Input Files" section does not have any such marks.
Finally, if either the month or day of month is specified as an element or list, and the day of week is also specified as an element or list, then any day matching either the month and day of month, or the day of week, shall be matched.
I have highlighted the word "shall", which leaves no doubt:
shall
For an implementation that conforms to POSIX.1-2017, describes a feature or behavior that is mandatory. An application can rely on the existence of the feature or behavior.
For an application or user, describes a behavior that is mandatory.
But, as a system administrator I would tend to consider the specification abstract, it cannot be wrong (unless it is so wrong it cannot be implemented). The fault, if any, is within an implementation if it does not conform to a claimed specification (possibly with the help of POSIXLY_CORRECT
which is the usual get-out-of-jail-free for implementors who bend the specification in the interest of sanity or user expectations).
Best Answer
The easiest way to get approximately every 14 days is to make it twice a month.
That syntax is explained in
man systemd.timer
;*-*-1,15
is the 1st and the 15th of every month of every year.If you wanted to try for exactly every fourteen days from when the service started:
But there's a catch here: I think you'd have to have the system up the whole time. There is a
Persistent
option to have "the time when the service unit was last triggered...stored on disk" but according to the man page "this setting only has an effect on timers configured with OnCalendar".