1Schedule::Cron(3)     User Contributed Perl Documentation    Schedule::Cron(3)
2
3
4

NAME

6       Cron - cron-like scheduler for Perl subroutines
7

SYNOPSIS

9         use Schedule::Cron;
10
11         # Subroutines to be called
12         sub dispatcher {
13           print "ID:   ",shift,"\n";
14           print "Args: ","@_","\n";
15         }
16
17         sub check_links {
18           # do something...
19         }
20
21         # Create new object with default dispatcher
22         my $cron = new Schedule::Cron(\&dispatcher);
23
24         # Load a crontab file
25         $cron->load_crontab("/var/spool/cron/perl");
26
27         # Add dynamically  crontab entries
28         $cron->add_entry("3 4  * * *",ROTATE => "apache","sendmail");
29         $cron->add_entry("0 11 * * Mon-Fri",\&check_links);
30
31         # Run scheduler
32         $cron->run(detach=>1);
33

DESCRIPTION

35       This module provides a simple but complete cron like scheduler.  I.e
36       this module can be used for periodically executing Perl subroutines.
37       The dates and parameters for the subroutines to be called are specified
38       with a format known as crontab entry (see "METHODS", add_entry() and
39       crontab(5))
40
41       The philosophy behind "Schedule::Cron" is to call subroutines
42       periodically from within one single Perl program instead of letting
43       "cron" trigger several (possibly different) Perl scripts. Everything
44       under one roof.  Furthermore, "Schedule::Cron" provides mechanism to
45       create crontab entries dynamically, which isn't that easy with "cron".
46
47       "Schedule::Cron" knows about all extensions (well, at least all
48       extensions I'm aware of, i.e those of the so called "Vixie" cron) for
49       crontab entries like ranges including 'steps', specification of month
50       and days of the week by name, or coexistence of lists and ranges in the
51       same field.  It even supports a bit more (like lists and ranges with
52       symbolic names).
53

METHODS

55       $cron = new Schedule::Cron($dispatcher,[extra args])
56           Creates a new "Cron" object.  $dispatcher is a reference to a
57           subroutine, which will be called by default.  $dispatcher will be
58           invoked with the arguments parameter provided in the crontab entry
59           if no other subroutine is specified. This can be either a single
60           argument containing the argument parameter literally has string
61           (default behavior) or a list of arguments when using the "eval"
62           option described below.
63
64           The date specifications must be either provided via a crontab like
65           file or added explicitly with add_entry() ("add_entry").
66
67           extra_args can be a hash or hash reference for additional
68           arguments.  The following parameters are recognized:
69
70           file => <crontab>
71               Load the crontab entries from <crontab>
72
73           eval =>  1
74               Eval the argument parameter in a crontab entry before calling
75               the subroutine (instead of literally calling the dispatcher
76               with the argument parameter as string)
77
78           nofork => 1
79               Don't fork when starting the scheduler. Instead, the jobs are
80               executed within current process. In your executed jobs, you
81               have full access to the global variables of your script and
82               hence might influence other jobs running at a different time.
83               This behaviour is fundamentally different to the 'fork' mode,
84               where each jobs gets its own process and hence a copy of the
85               process space, independent of each other job and the main
86               process. This is due to the nature of the  "fork" system call.
87
88           nostatus =>  1
89               Do not update status in $0.  Set this if you don't want ps to
90               reveal the internals of your application, including job
91               argument lists.  Default is 0 (update status).
92
93           skip => 1
94               Skip any pending jobs whose time has passed. This option is
95               only useful in combination with "nofork" where a job might
96               block the execution of the following jobs for quite some time.
97               By default, any pending job is executed even if its scheduled
98               execution time has already passed. With this option set to true
99               all pending which would have been started in the meantime are
100               skipped.
101
102           catch => 1
103               Catch any exception raised by a job. This is especially useful
104               in combination with the "nofork" option to avoid stopping the
105               main process when a job raises an exception (dies).
106
107           after_job => \&after_sub
108               Call a subroutine after a job has been run. The first argument
109               is the return value of the dispatched job, the reminding
110               arguments are the arguments with which the dispatched job has
111               been called.
112
113               Example:
114
115                  my $cron = new Schedule::Cron(..., after_job => sub {
116                         my ($ret,@args) = @_;
117                         print "Return value: ",$ret," - job arguments: (",join ":",@args,")\n";
118                  });
119
120           log => \&log_sub
121               Install a logging subroutine. The given subroutine is called
122               for several events during the lifetime of a job. This method is
123               called with two arguments: A log level of 0 (info),1 (warning)
124               or 2 (error) depending on the importance of the message and the
125               message itself.
126
127               For example, you could use Log4perl (<http://log4perl.sf.net>)
128               for logging purposes for example like in the following code
129               snippet:
130
131                  use Log::Log4perl;
132                  use Log::Log4perl::Level;
133
134                  my $log_method = sub {
135                     my ($level,$msg) = @_;
136                     my $DBG_MAP = { 0 => $INFO, 1 => $WARN, 2 => $ERROR };
137
138                     my $logger = Log::Log4perl->get_logger("My::Package");
139                     $logger->log($DBG_MAP->{$level},$msg);
140                  }
141
142                  my $cron = new Schedule::Cron(.... , log => $log_method);
143
144           loglevel => <-1,0,1,2>
145               Restricts logging to the specified severity level or below.
146               Use 0 to have all messages generated, 1 for only warnings and
147               errors and 2 for errors only.  Default is 0 (all messages).  A
148               loglevel of -1 (debug) will include job argument lists (also in
149               $0) in the job start message logged with a level of 0 or above.
150               You may have security concerns with this. Unless you are
151               debugging, use 0 or higher. A value larger than 2 will disable
152               logging completely.
153
154               Although you can filter in your log routine, generating the
155               messages can be expensive, for example if you pass arguments
156               pointing to large hashes.  Specifying a loglevel avoids
157               formatting data that your routine would discard.
158
159           processprefix => <name>
160               Cron::Schedule sets the process' name (i.e. $0) to contain some
161               informative messages like when the next job executes or with
162               which arguments a job is called. By default, the prefix for
163               this labels is "Schedule::Cron". With this option you can set
164               it to something different. You can e.g. use $0 to include the
165               original process name.  You can inhibit this with the
166               "nostatus" option, and prevent the argument display by setting
167               "loglevel" to zero or higher.
168
169           processname => <name>
170               Set the process name (i.e. $0) to a literal string. Using this
171               setting overrides "processprefix" and "nostatus".
172
173           sleep => \&hook
174               If specified, &hook will be called instead of sleep(), with the
175               time to sleep in seconds as first argument and the
176               Schedule::Cron object as second.  This hook allows you to use
177               select() instead of sleep, so that you can handle IO, for
178               example job requests from a network connection.
179
180               e.g.
181
182                 $cron->run( { sleep => \&sleep_hook, nofork => 1 } );
183
184                 sub sleep_hook {
185                   my ($time, $cron) = @_;
186
187                   my ($rin, $win, $ein) = ('','','');
188                   my ($rout, $wout, $eout);
189                   vec($rin, fileno(STDIN), 1) = 1;
190                   my ($nfound, $ttg) = select($rout=$rin, $wout=$win, $eout=$ein, $time);
191                   if ($nfound) {
192                          handle_io($rout, $wout, $eout);
193                   }
194                   return;
195               }
196
197       $cron->load_crontab($file)
198       $cron->load_crontab(file=>$file,[eval=>1])
199           Loads and parses the crontab file $file. The entries found in this
200           file will be added to the current time table with
201           "$cron->add_entry".
202
203           The format of the file consists of cron commands containing of
204           lines with at least 5 columns, whereas the first 5 columns specify
205           the date.  The rest of the line (i.e columns 6 and greater)
206           contains the argument with which the dispatcher subroutine will be
207           called.  By default, the dispatcher will be called with one single
208           string argument containing the rest of the line literally.
209           Alternatively, if you call this method with the optional argument
210           "eval=>1" (you must then use the second format shown above), the
211           rest of the line will be evaled before used as argument for the
212           dispatcher.
213
214           For the format of the first 5 columns, please see "add_entry".
215
216           Blank lines and lines starting with a "#" will be ignored.
217
218           There's no way to specify another subroutine within the crontab
219           file.  All calls will be made to the dispatcher provided at
220           construction time.
221
222           If    you   want    to    start   up    fresh,    you   should
223           call "$cron->clean_timetable()" before.
224
225           Example of a crontab fiqw(le:)
226
227              # The following line runs on every Monday at 2:34 am
228              34 2 * * Mon  "make_stats"
229              # The next line should be best read in with an eval=>1 argument
230              *  * 1 1 *    { NEW_YEAR => '1',HEADACHE => 'on' }
231
232       $cron->add_entry($timespec,[arguments])
233           Adds a new entry to the list of scheduled cron jobs.
234
235           Time and Date specification
236
237           $timespec is the specification of the scheduled time in crontab
238           format (crontab(5)) which contains five mandatory time and date
239           fields and an optional 6th column. $timespec can be either a plain
240           string, which contains a whitespace separated time and date
241           specification.  Alternatively, $timespec can be a reference to an
242           array containing the five elements for the date fields.
243
244           The time and date fields are (taken mostly from crontab(5), "Vixie"
245           cron):
246
247              field          values
248              =====          ======
249              minute         0-59
250              hour           0-23
251              day of month   1-31
252              month          1-12 (or as names)
253              day of week    0-7 (0 or 7 is Sunday, or as names)
254              seconds        0-59 (optional)
255
256            A field may be an asterisk (*), which always stands for
257            ``first-last''.
258
259            Ranges of numbers are  allowed.  Ranges are two numbers
260            separated  with  a  hyphen.   The  specified  range  is
261            inclusive.   For example, 8-11  for an  ``hours'' entry
262            specifies execution at hours 8, 9, 10 and 11.
263
264            Lists  are allowed.   A list  is a  set of  numbers (or
265            ranges)  separated by  commas.   Examples: ``1,2,5,9'',
266            ``0-4,8-12''.
267
268            Step  values can  be used  in conjunction  with ranges.
269            Following a range with ``/<number>'' specifies skips of
270            the  numbers value  through the  range.   For example,
271            ``0-23/2'' can  be used in  the hours field  to specify
272            command execution every  other hour (the alternative in
273            the V7 standard is ``0,2,4,6,8,10,12,14,16,18,20,22'').
274            Steps are  also permitted after an asterisk,  so if you
275            want to say ``every two hours'', just use ``*/2''.
276
277            Names can also  be used for the ``month''  and ``day of
278            week''  fields.  Use  the  first three  letters of  the
279            particular day or month (case doesn't matter).
280
281            Note: The day of a command's execution can be specified
282                  by two fields  -- day of month, and  day of week.
283                  If both fields are restricted (ie, aren't *), the
284                  command will be run when either field matches the
285                  current  time.  For  example, ``30  4 1,15  * 5''
286                  would cause a command to be run at 4:30 am on the
287                  1st and 15th of each month, plus every Friday
288
289           Examples:
290
291            "8  0 * * *"         ==> 8 minutes after midnight, every day
292            "5 11 * * Sat,Sun"   ==> at 11:05 on each Saturday and Sunday
293            "0-59/5 * * * *"     ==> every five minutes
294            "42 12 3 Feb Sat"    ==> at 12:42 on 3rd of February and on
295                                     each Saturday in February
296            "32 11 * * * 0-30/2" ==> 11:32:00, 11:32:02, ... 11:32:30 every
297                                     day
298
299           In addition, ranges or lists of names are allowed.
300
301           An optional sixth column can be used to specify the seconds within
302           the minute. If not present, it is implicitly set to "0".
303
304           Command specification
305
306           The subroutine to be executed when the $timespec matches can be
307           specified in several ways.
308
309           First, if the optional "arguments" are lacking, the default
310           dispatching subroutine provided at construction time will be called
311           without arguments.
312
313           If the second parameter to this method is a reference to a
314           subroutine, this subroutine will be used instead of the dispatcher.
315
316           Any additional parameters will be given as arguments to the
317           subroutine to be executed.  You can also specify a reference to an
318           array instead of a list of parameters.
319
320           You can also use a named parameter list provided as an hashref.
321           The named parameters recognized are:
322
323           subroutine
324           sub Reference to subroutine to be executed
325
326           arguments
327           args
328               Reference to array containing arguments to be use when calling
329               the subroutine
330
331           eval
332               If true, use the evaled string provided with the "arguments"
333               parameter.  The evaluation will take place immediately (not
334               when the subroutine is going to be called)
335
336           Examples:
337
338              $cron->add_entry("* * * * *");
339              $cron->add_entry("* * * * *","doit");
340              $cron->add_entry("* * * * *",\&dispatch,"first",2,"third");
341              $cron->add_entry("* * * * *",{'subroutine' => \&dispatch,
342                                            'arguments'  => [ "first",2,"third" ]});
343              $cron->add_entry("* * * * *",{'subroutine' => \&dispatch,
344                                            'arguments'  => '[ "first",2,"third" ]',
345                                            'eval'       => 1});
346
347       @entries = $cron->list_entries()
348           Return a list of cron entries. Each entry is a hash reference of
349           the following form:
350
351             $entry = {
352                        time => $timespec,
353                        dispatch => $dispatcher,
354                        args => $args_ref
355                      }
356
357           Here $timespec is the specified time in crontab format as provided
358           to "add_entry", $dispatcher is a reference to the dispatcher for
359           this entry and $args_ref is a reference to an array holding
360           additional arguments (which can be an empty array reference). For
361           further explanation of this arguments refer to the documentation of
362           the method "add_entry".
363
364           The order index of each entry can be used within "update_entry",
365           "get_entry" and "delete_entry". But be aware, when you are deleting
366           an entry, that you have to refetch the list, since the order will
367           have changed.
368
369           Note that these entries are returned by value and were obtained
370           from the internal list by a deep copy. I.e. you are free to modify
371           it, but this won't influence the original entries. Instead use
372           "update_entry" if you need to modify an existing crontab entry.
373
374       $entry = $cron->get_entry($idx)
375           Get a single entry. $entry is either a hashref with the possible
376           keys "time", "dispatch" and "args" (see list_entries()) or undef if
377           no entry with the given index $idx exists.
378
379       $cron->delete_entry($idx)
380           Delete the entry at index $idx. Returns the deleted entry on
381           success, "undef" otherwise.
382
383       $cron->update_entry($idx,$entry)
384           Updates the entry with index $idx. $entry is a hash ref as
385           described in list_entries() and must contain at least a value
386           "$entry->{time}". If no "$entry->{dispatcher}" is given, then the
387           default dispatcher is used.  This method returns the old entry on
388           success, "undef" otherwise.
389
390       $cron->run([options])
391           This method starts the scheduler.
392
393           When called without options, this method will never return and
394           executes the scheduled subroutine calls as needed.
395
396           Alternatively, you can detach the main scheduler loop from the
397           current process (daemon mode). In this case, the pid of the forked
398           scheduler process will be returned.
399
400           The "options" parameter specifies the running mode of
401           "Schedule::Cron".  It can be either a plain list which will be
402           interpreted as a hash or it can be a reference to a hash. The
403           following named parameters (keys of the provided hash) are
404           recognized:
405
406           detach
407               If set to a true value the scheduler process is detached from
408               the current process (UNIX only).
409
410           pid_file
411               If running in daemon mode, name the optional file, in which the
412               process id of the scheduler process should be written. By
413               default, no PID File will be created.
414
415           nofork, skip, catch, log, loglevel, nostatus, sleep
416               See new() for a description of these configuration parameters,
417               which can be provided here as well. Note, that the options
418               given here overrides those of the constructor.
419
420           Examples:
421
422              # Start  scheduler, detach  from current  process and
423              # write  the  PID  of  the forked  scheduler  to  the
424              # specified file
425              $cron->run(detach=>1,pid_file=>"/var/run/scheduler.pid");
426
427              # Start scheduler and wait forever.
428              $cron->run();
429
430       $cron->clean_timetable()
431           Remove all scheduled entries
432
433       $cron->check_entry($id)
434           Check, whether the given ID is already registered in the timetable.
435           A ID is the first argument in the argument parameter of the a
436           crontab entry.
437
438           Returns (one of) the index in the  timetable (can be 0, too) if the
439           ID could be found or "undef" otherwise.
440
441           Example:
442
443              $cron->add_entry("* * * * *","ROTATE");
444              .
445              .
446              defined($cron->check_entry("ROTATE")) || die "No ROTATE entry !"
447
448       $cron->get_next_execution_time($cron_entry,[$ref_time])
449           Well, this is mostly an internal method, but it might be useful on
450           its own.
451
452           The purpose of this method is to calculate the next execution time
453           from a specified crontab entry
454
455           Parameters:
456
457           $cron_entry
458               The crontab entry as specified in "add_entry"
459
460           $ref_time
461               The reference time for which the next time should be searched
462               which matches $cron_entry. By default, take the current time
463
464           This method returns the number of epoch-seconds of the next matched
465           date for $cron_entry.
466
467           Since I suspect, that this calculation of the next execution time
468           might fail in some circumstances (bugs are lurking everywhere ;-)
469           an additional interactive method bug() is provided for checking
470           crontab entries against your expected output. Refer to the top-
471           level README for additional usage information for this method.
472
473       $cron->set_timeshift($ts)
474           Modify global time shift for all timetable. The timeshift is subbed
475           from localtime to calculate next execution time for all scheduled
476           jobs.
477
478           ts parameter must be in seconds. Default value is 0. Negative
479           values are allowed to shift time in the past.
480
481           Returns actual timeshift in seconds.
482
483           Example:
484
485              $cron->set_timeshift(120);
486
487              Will delay all jobs 2 minutes in the future.
488

DST ISSUES

490       Daylight saving occurs typically twice a year: In the first switch, one
491       hour is skipped. Any job which triggers in this skipped hour will be
492       fired in the next hour. So, when the DST switch goes from 2:00 to 3:00
493       a job which is scheduled for 2:43 will be executed at 3:43.
494
495       For the reverse backwards switch later in the year, the behaviour is
496       undefined. Two possible behaviours can occur: For jobs triggered in
497       short intervals, where the next execution time would fire in the extra
498       hour as well, the job could be executed again or skipped in this extra
499       hour. Currently, running "Schedule::Cron" in "MET" would skip the extra
500       job, in "PST8PDT" it would execute a second time. The reason is the way
501       how Time::ParseDate calculates epoch times for dates given like
502       "02:50:00 2009/10/25". Should it return the seconds since 1970 for this
503       time happening 'first', or for this time in the extra hour ? As it
504       turns out, Time::ParseDate returns the epoch time of the first
505       occurrence for "PST8PDT" and for "MET" it returns the second
506       occurrence. Unfortunately, there is no way to specify which entry
507       Time::ParseDate should pick (until now). Of course, after all, this is
508       obviously not Time::ParseDate's fault, since a simple date
509       specification within the DST backswitch period is ambiguous. However,
510       it would be nice if the parsing behaviour of Time::ParseDate would be
511       consistent across time zones (a ticket has be raised for fixing this).
512       Then Schedule::Cron's behaviour within a DST backward switch would be
513       consistent as well.
514
515       Since changing the internal algorithm which worked now for over ten
516       years would be too risky and I don't see any simple solution for this
517       right now, it is likely that this undefined behaviour will exist for
518       some time. Maybe some hero is coming along and will fix this, but this
519       is probably not me ;-)
520
521       Sorry for that.
522

AUTHORS

524       Roland Huß <roland@consol.de>
525
526       Currently maintained by Nicholas Hubbard <nicholashubbard@posteo.net>
527

CONTRIBUTORS

529       •   Alexandr Ciornii <alexchorny@gmail.com>
530
531       •   Andrew Danforth
532
533       •   Andy Ford
534
535       •   Bray Jones
536
537       •   Clinton Gormley
538
539       •   Eric Wilhelm
540
541       •   Frank Mayer
542
543       •   Jamie McCarthy
544
545       •   Loic Paillotin
546
547       •   Nicholas Hubbard <nicholashubbard@posteo.net>
548
549       •   Peter Vary
550
551       •   Philippe Verdret
552
554       Copyright (c) 1999-2013 Roland Huß.
555
556       Copyright (c) 2022 Nicholas Hubbard.
557
558       This library is free software; you can redistribute it and/or modify it
559       under the same terms as Perl itself.
560

POD ERRORS

562       Hey! The above document had some coding errors, which are explained
563       below:
564
565       Around line 1916:
566           Non-ASCII character seen before =encoding in 'Huß'. Assuming UTF-8
567
568
569
570perl v5.36.0                      2023-01-20                 Schedule::Cron(3)
Impressum