]> git.netwichtig.de Git - user/henk/code/snooze.git/blob - README.md
5831e81f4a6e569cc4951f589b7b84453faca3b6
[user/henk/code/snooze.git] / README.md
1 ## snooze: run a command at a particular time
2
3 `snooze` is a new tool for to wait until a particular time and then
4 run a command.  Together with a service supervision system such as runit,
5 this can be used to replace cron(8).
6
7 `lr` has been tested on Linux 4.2.
8 It will likely work on other Unix-like systems with C99.
9
10 ## Benefits
11
12 Over cron:
13 - mnemonic syntax
14 - no overlapping job runs possible
15 - filtering by ISO week and day of year
16 - due to supervision, no centralized daemon required
17 - due to supervision, can easily disable jobs or force their
18   execution instantly
19 - due to supervision, have custom logs
20 - due to no centralized daemon, no fuzzing with multiple users/permissions
21 - very robust with respect to external time changes
22 - can use a file timestamp to ensure minimum waiting time between two
23   runs, even across reboots
24 - randomized delays (some cron have that)
25 - variable slack (no need for anacron)
26
27 Over runwhen:
28 - less confusing usage (I hope)
29 - filtering by ISO week and day of year
30 - zero dependencies
31
32 Over uschedule:
33 - due to supervision, no centralized daemon required
34
35 ## Rosetta stone
36
37 * run five minutes after midnight, every day:
38   cron: `5 0 * * *`
39   snooze: `-M5`
40 * run at 2:15pm on the first of every month:
41   cron: `15 14 1 * *`
42   snooze: `-d1 -H2 -M15`
43 * run at 10 pm on weekdays:
44   cron: `0 22 * * 1-5`
45   snooze: `-w1-5 -H22`
46 * run 23 minutes after midn, 2am, 4am ..., everyday:
47   cron: 23 0-23/2 * * *
48   snooze: `-H/2 -M23`
49 * run every second week:
50   snooze: `-W/2`
51 * run every 10 days:
52   snooze: `-D/10`
53
54 ## Usage:
55
56         snooze [-nv] [-t timefile] [-T timewait] [-R randdelay] [-s slack] [-d mday] [-m mon] [-w wday] [-D yday] [-W yweek] [-H hour] [-M min] [-S sec] COMMAND...
57
58 * `-n`: dry-run, print the next 5 times the command would run.
59 * `-v`: verbose, print scheduled (and rescheduled) times.
60 * `-t`, `-T`: see below timefiles
61 * `-R`: add between 0 and RANDDELAY seconds to the scheduled time.
62 * `-s`: commands are executed even if they are SLACK (default: 60) seconds late.
63
64 The remaining arguments are patterns for the time fields:
65
66 * `-d`: day of month
67 * `-m`: month
68 * `-w`: weekday (0-7, sunday is 0 and 7)
69 * `-D`: day of year
70 * `-W`: ISO week of year (0..53)
71 * `-H`: hour
72 * `-M`: minute
73 * `-S`: second
74
75 The following syntax is used for these options:
76
77 * exact match: `-d 3`, run on the 3rd
78 * alternation: `-d 3,10,27`, run on 3rd, 10th, 27th
79 * range: `-d 1-5`, run on 1st, 2nd, 3rd, 4th, 5th
80 * star: `-d '*'`, run every day
81 * repetition: `-d /5`, run on 5th, 10th, 15th, 20th, 25th, 30th day
82 * shifted repetition: `-d 2/5`, run on 7th, 12th, 17th, 22nd, 27th day
83
84 and combinations of those, e.g. `-d 1-10,15/5,28`.
85
86 The defaults are `-d* -m* -w* -D* -W* -H0 -M0 -S0`, that is, every midnight.
87
88 Note that *all* patterns need to match (contrary to cron where either
89 day of month *or* day of week matches), so `-w5 -d13` only runs on
90 Friday the 13th.
91
92 ## Timefiles
93
94 Optionally, you can keep track of runs in time files, using `-t` and
95 optionally `-T`.
96
97 When `-T` is passed, execution will not start earlier than the mtime
98 of TIMEFILE plus TIMEWAIT seconds.
99
100 When `-T` is *not* passed, snooze will start finding the first matching time
101 starting from the mtime of TIMEFILE, and taking SLACK into account.
102 (E.g. `-H0 -s$((24*60*60)) -t timefile` will start an instant
103 execution when timefile has not been touched today, whereas without `-t`
104 this would always wait until next midnight.)
105
106 If TIMEFILE does not exist, it will be assumed outdated enough to
107 ensure earliest execution.
108
109 snooze does not update the timefiles, you need to do that!
110 Only mtime is looked at, so touch(1) is good.
111
112 ## Exact behavior
113
114 * snooze parses the option flags and computes the first time the
115   date pattern matches, as a symbolic date
116 * if a timefile is specified, the time is upped to timefile + timewait seconds
117 * if a random delay is requested, it is added
118 * snooze computes how far this event is in the future
119 * snooze sleeps that long, but at most 5 minutes
120 * after waking, snooze recomputes how far the event is in the future
121 * if the event is in the past, but fewer than SLACK seconds, snooze
122   execs the command.  You need to ensure (by setting up supervision)
123   snooze runs again after that!
124 * if we woke due to a SIGALRM, the command is executed immediately as well
125 * if the event is in the future, recompute the time it takes, possibly
126   considering shifting of the system time or timezone changes
127   (possibly only works on glibc)
128 * If no command was given, just return with status 0
129 * and so on...
130
131 ## Common usages
132
133 Run a job like cron, every day at 7am and 7pm:
134
135         exec snooze -H7,19 rdumpfs / /data/dump/mybox 2>&1
136
137 Run a job daily, never twice a day:
138
139         exec snooze -H0 -S $((24*60*60)) -t timefile \
140                 sh -c 'run-parts /etc/cron.daily; touch timefile'
141
142 Use snooze inline, run a mirror script every hour at 30 minutes past,
143 but ensure there are at least 20 minutes in between.
144
145         set -e
146         snooze -H'*' -M30 -t timefile -T $((20*60))
147         touch timefile  # remove this if instantly retrying on failure is ok
148         mirrorallthethings
149         touch timefile
150
151 Use snooze inline, cron-style mail:
152
153         set -e
154         snooze ...
155         actualjob >output 2>&1 ||
156                 mail -s "$(hostname): snooze job failed with status $?" root <output
157
158 ## Installation
159
160 Use `make all` to build, `make install` to install relative to `PREFIX`
161 (`/usr/local` by default).  The `DESTDIR` convention is respected.
162 You can also just copy the binary into your `PATH`.
163
164 ## Copyright
165
166 snooze is in the public domain.
167
168 To the extent possible under law,
169 Christian Neukirchen <chneukirchen@gmail.com>
170 has waived all copyright and related or
171 neighboring rights to this work.
172
173 http://creativecommons.org/publicdomain/zero/1.0/