From b52f87ed751fc47dd50a92be65dcaab79ca034cc Mon Sep 17 00:00:00 2001 From: Martin von Gagern Date: Fri, 18 Mar 2016 00:10:31 +0100 Subject: [PATCH 1/2] Allow dot in cron.update to re-scan whole directory --- crond.markdown | 11 ++++++++++- database.c | 4 +++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/crond.markdown b/crond.markdown index d3772bb..389b958 100644 --- a/crond.markdown +++ b/crond.markdown @@ -1,6 +1,6 @@ % CROND(8) % -% 1 May 2011 +% 18 Mar 2016 NAME ==== @@ -154,6 +154,10 @@ to "cron.update". This request that user clio's job1 should be scheduled tag), and job2 should also be scheduled (without waiting for other jobs). See crontab(1) for more about tags and named jobs. +Instead of naming a file inside the directory, a single dot can be +used to name the directory as a whole. So one can trigger a re-read +of all user's crontabs by writing a dot to "cron.update". + The directory of per-user crontabs is re-parsed once every hour in any case. @@ -161,6 +165,11 @@ Any crontabs in the system directory (usually /etc/cron.d) are parsed at the same time. This directory can be used by packaging systems. When you install a package foo, it might write its own foo-specific crontab to /etc/cron.d/foo. +Package managers are encouraged to check whether dcron is installed, +and if so, write a dot to /etc/cron.d/cron.update after packages got +installed or removed, in order to more quickly trigger a re-read of +those files. + The superuser has a per-user crontab along with other users. It usually resides at /var/spool/cron/crontabs/root. diff --git a/database.c b/database.c index c0cdc11..a941fdb 100644 --- a/database.c +++ b/database.c @@ -125,7 +125,9 @@ CheckUpdates(const char *dpath, const char *user_override, time_t t1, time_t t2) */ fname = strtok_r(buf, " \t\n", &ptok); - if (user_override) + if (!strcmp(fname, ".")) + SynchronizeDir(dpath, user_override, 0); + else if (user_override) SynchronizeFile(dpath, fname, user_override); else if (!getpwnam(fname)) printlogf(LOG_WARNING, "ignoring %s/%s (non-existent user)\n", dpath, fname); From da3bbd01b2110d895bf8d09d858f381186c57381 Mon Sep 17 00:00:00 2001 From: Martin von Gagern Date: Fri, 18 Mar 2016 00:14:45 +0100 Subject: [PATCH 2/2] Re-create man pages --- crond.8 | 274 +++++++++++++++++++++++++++--------------------------- crontab.1 | 239 +++++++++++++++++++++++------------------------ 2 files changed, 252 insertions(+), 261 deletions(-) diff --git a/crond.8 b/crond.8 index 1582235..9db0c67 100644 --- a/crond.8 +++ b/crond.8 @@ -1,193 +1,188 @@ -.TH CROND 8 "1 May 2011" +.TH "CROND" "8" "18 Mar 2016" "" "" .SH NAME .PP -crond - dillon's lightweight cron daemon +crond \- dillon\[aq]s lightweight cron daemon .SH SYNOPSIS .PP -\f[B]crond [-s dir] [-c dir] [-t dir] [-m user\@host] [-M mailhandler] [-S|-L file] [-l loglevel] [-b|-f|-d]\f[] +\f[B]crond [\-s dir] [\-c dir] [\-t dir] [\-m user\@host] [\-M +mailhandler][\-S|\-L file] [\-l loglevel] [\-b|\-f|\-d]\f[] .SH OPTIONS .PP -\f[B]crond\f[] is a background daemon that parses individual -crontab files and executes commands on behalf of the users in -question. +\f[B]crond\f[] is a background daemon that parses individual crontab +files and executes commands on behalf of the users in question. .TP -.B -s dir +.B \-s dir directory of system crontabs (defaults to /etc/cron.d) .RS .RE .TP -.B -c dir -directory of per-user crontabs (defaults to -/var/spool/cron/crontabs) +.B \-c dir +directory of per\-user crontabs (defaults to /var/spool/cron/crontabs) .RS .RE .TP -.B -t dir -directory of timestamps for \@freq and FREQ=\&... jobs (defaults to -/var/spool/cron/cronstamps) +.B \-t dir +directory of timestamps for \@freq and FREQ=... +jobs (defaults to /var/spool/cron/cronstamps) .RS .RE .TP -.B -m user\@host -where should the output of cronjobs be directed? (defaults to local -user) Some mail handlers (like msmtp) can't route mail to local -users. -If that's what you're using, then you should supply a remote +.B \-m user\@host +where should the output of cronjobs be directed? +(defaults to local user) Some mail handlers (like msmtp) can\[aq]t route +mail to local users. +If that\[aq]s what you\[aq]re using, then you should supply a remote address using this switch. Cron output for all users will be directed to that address. -Alternatively, you could supply a different mail handler using the --M switch, to log or otherwise process the messages instead of -mailing them. -Alternatively, you could just direct the stdout and stderr of your -cron jobs to /dev/null. +Alternatively, you could supply a different mail handler using the \-M +switch, to log or otherwise process the messages instead of mailing +them. +Alternatively, you could just direct the stdout and stderr of your cron +jobs to /dev/null. .RS .RE .TP -.B -M mailhandler -Any output that cronjobs print to stdout or stderr gets formatted -as an email and piped to \f[C]/usr/sbin/sendmail\ -t\ -oem\ -i\f[]. +.B \-M mailhandler +Any output that cronjobs print to stdout or stderr gets formatted as an +email and piped to \f[C]/usr/sbin/sendmail\ \-t\ \-oem\ \-i\f[]. Attempts to mail this are also logged. -This switch permits the user to substitute a different mailhandler, -or a script, for sendmail. -That custom mailhandler is called with no arguments, and with the -mail headers and cronjob output supplied to stdin. -When a custom mailhandler is used, mailing is no longer logged -(have your mailhandler do that if you want it). -When cron jobs generate no stdout or stderr, nothing is sent to -either sendmail or a custom mailhandler. +This switch permits the user to substitute a different mailhandler, or a +script, for sendmail. +That custom mailhandler is called with no arguments, and with the mail +headers and cronjob output supplied to stdin. +When a custom mailhandler is used, mailing is no longer logged (have +your mailhandler do that if you want it). +When cron jobs generate no stdout or stderr, nothing is sent to either +sendmail or a custom mailhandler. .RS .RE .TP -.B -S +.B \-S log events to syslog, using syslog facility LOG_CRON and identity -`crond' (this is the default behavior). +\[aq]crond\[aq] (this is the default behavior). .RS .RE .TP -.B -L file +.B \-L file log to specified file instead of syslog. .RS .RE .TP -.B -l loglevel +.B \-l loglevel log events at the specified, or more important, loglevels. -The default is `notice'. -Valid level names are as described in logger(1) and syslog(3): -alert, crit, debug, emerg, err, error (deprecated synonym for err), -info, notice, panic (deprecated synonym for emerg), warning, warn -(deprecated synonym for warning). +The default is \[aq]notice\[aq]. +Valid level names are as described in logger(1) and syslog(3): alert, +crit, debug, emerg, err, error (deprecated synonym for err), info, +notice, panic (deprecated synonym for emerg), warning, warn (deprecated +synonym for warning). .RS .RE .TP -.B -b -run \f[B]crond\f[] in the background (default unless -d or -f is +.B \-b +run \f[B]crond\f[] in the background (default unless \-d or \-f is specified) .RS .RE .TP -.B -f +.B \-f run \f[B]crond\f[] in the foreground. -All log messages are sent to stderr instead of syslog or a -L file. +All log messages are sent to stderr instead of syslog or a \-L file. .RS .RE .TP -.B -d +.B \-d turn on debugging. -This option sets the logging level to `debug' and causes +This option sets the logging level to \[aq]debug\[aq] and causes \f[B]crond\f[] to run in the foreground. .RS .RE .SH DESCRIPTION .PP -\f[B]crond\f[] is responsible for scanning the crontab files and -running their commands at the appropriate time. -It always synchronizes to the top of the minute, matching the -current time against its internal list of parsed crontabs. +\f[B]crond\f[] is responsible for scanning the crontab files and running +their commands at the appropriate time. +It always synchronizes to the top of the minute, matching the current +time against its internal list of parsed crontabs. That list is stored so that it can be scanned very quickly, and \f[B]crond\f[] can deal with several hundred crontabs with several thousand entries without using noticeable CPU. .PP -Cron jobs are not re-executed if a previous instance of them is -still running. -For example, if you have a crontab command \f[C]sleep\ 70\f[], that -you request to be run every minute, \f[B]crond\f[] will skip this -job when it sees it is still running. -So the job won't be run more frequently than once every two -minutes. +Cron jobs are not re\-executed if a previous instance of them is still +running. +For example, if you have a crontab command \f[C]sleep\ 70\f[], that you +request to be run every minute, \f[B]crond\f[] will skip this job when +it sees it is still running. +So the job won\[aq]t be run more frequently than once every two minutes. If you do not like this feature, you can run your commands in the background with an \f[C]&\f[]. .PP -\f[B]crond\f[] automatically detects when the clock has been -changed, during its per-minute scans. -Backwards time-changes of an hour or less won't re-run cron jobs +\f[B]crond\f[] automatically detects when the clock has been changed, +during its per\-minute scans. +Backwards time\-changes of an hour or less won\[aq]t re\-run cron jobs from the intervening period. -\f[B]crond\f[] will effectively sleep until it catches back up to -the original time. -Forwards time-changes of an hour or less (or if the computer is -suspended and resumed again within an hour) will run any missed -jobs exactly once. -Changes greater than an hour in either direction cause -\f[B]crond\f[] to re-calculate when jobs should be run, and not -attempt to execute any missed commands. -This is effectively the same as if \f[B]crond\f[] had been stopped -and re-started. -.PP -For example, suppose it's 10 am, and a job is scheduled to run -every day at 10:30 am. -If you set the system's clock forward to 11 am, crond will +\f[B]crond\f[] will effectively sleep until it catches back up to the +original time. +Forwards time\-changes of an hour or less (or if the computer is +suspended and resumed again within an hour) will run any missed jobs +exactly once. +Changes greater than an hour in either direction cause \f[B]crond\f[] to +re\-calculate when jobs should be run, and not attempt to execute any +missed commands. +This is effectively the same as if \f[B]crond\f[] had been stopped and +re\-started. +.PP +For example, suppose it\[aq]s 10 am, and a job is scheduled to run every +day at 10:30 am. +If you set the system\[aq]s clock forward to 11 am, crond will immediately run the 10:30 job. -If on the other hand you set the system's clock forward to noon, -the 10:30 am job will be skipped until the next day. +If on the other hand you set the system\[aq]s clock forward to noon, the +10:30 am job will be skipped until the next day. Jobs scheduled using \@daily and the like work differently; see crontab(1) for details. .PP -\f[B]crond\f[] has a number of built in limitations to reduce the -chance of it being ill-used. -Potentially infinite loops during parsing are dealt with via a -failsafe counter, and non-root crontabs are limited to 256 crontab -entries. +\f[B]crond\f[] has a number of built in limitations to reduce the chance +of it being ill\-used. +Potentially infinite loops during parsing are dealt with via a failsafe +counter, and non\-root crontabs are limited to 256 crontab entries. Crontab lines may not be longer than 1024 characters, including the newline. .PP -Whenever \f[B]crond\f[] must run a job, it first creates a -daemon-owned temporary file O_EXCL and O_APPEND to store any -output, then fork()s and changes its user and group permissions to -match that of the user the job is being run for, then -\f[B]exec\f[]s \f[B]/bin/sh -c \f[] to run the job. -The temporary file remains under the ownership of the daemon to -prevent the user from tampering with it. -Upon job completion, \f[B]crond\f[] verifies the secureness of the -mail file and, if it has been appended to, mails the file to the -specified address. -The \f[B]sendmail\f[] program (or custom mail handler, if supplied) -is run under the user's uid to prevent mail related security holes. +Whenever \f[B]crond\f[] must run a job, it first creates a daemon\-owned +temporary file O_EXCL and O_APPEND to store any output, then fork()s and +changes its user and group permissions to match that of the user the job +is being run for, then \f[B]exec\f[]s \f[B]/bin/sh \-c \f[] to run the +job. +The temporary file remains under the ownership of the daemon to prevent +the user from tampering with it. +Upon job completion, \f[B]crond\f[] verifies the secureness of the mail +file and, if it has been appended to, mails the file to the specified +address. +The \f[B]sendmail\f[] program (or custom mail handler, if supplied) is +run under the user\[aq]s uid to prevent mail related security holes. .PP When a user edits their crontab, \f[B]crontab\f[] first copies the -crontab to a user owned file before running the user's preferred +crontab to a user owned file before running the user\[aq]s preferred editor. -The suid \f[B]crontab\f[] keeps an open descriptor to the file -which it later uses to copy the file back, thereby ensuring the -user has not tampered with the file type. -.PP -\f[B]crontab\f[] notifies \f[B]crond\f[] that a user's crontab file -has been modified (or created or deleted) through the -\[lq]cron.update\[rq] file, which resides in the per-user crontabs -directory (usually /var/spool/cron/crontabs). -\f[B]crontab\f[] appends the filename of the modified crontab file -to \[lq]cron.update\[rq]; and \f[B]crond\f[] inspects this file to -determine when to reparse or otherwise update its internal list of -parsed crontabs. -.PP -Whenever a \[lq]cron.update\[rq] file is seen, \f[B]crond\f[] also -re-reads timestamp files from its timestamp directory (usually +The suid \f[B]crontab\f[] keeps an open descriptor to the file which it +later uses to copy the file back, thereby ensuring the user has not +tampered with the file type. +.PP +\f[B]crontab\f[] notifies \f[B]crond\f[] that a user\[aq]s crontab file +has been modified (or created or deleted) through the "cron.update" +file, which resides in the per\-user crontabs directory (usually +/var/spool/cron/crontabs). +\f[B]crontab\f[] appends the filename of the modified crontab file to +"cron.update"; and \f[B]crond\f[] inspects this file to determine when +to reparse or otherwise update its internal list of parsed crontabs. +.PP +Whenever a "cron.update" file is seen, \f[B]crond\f[] also re\-reads +timestamp files from its timestamp directory (usually /var/spool/cron/cronstamps). -Normally these will just mirror \f[B]crond\f[]'s own internal -representations, but this mechanism could be used to manually -notify \f[B]crond\f[] that you've externally updated the -timestamps. +Normally these will just mirror \f[B]crond\f[]\[aq]s own internal +representations, but this mechanism could be used to manually notify +\f[B]crond\f[] that you\[aq]ve externally updated the timestamps. .PP -The \[lq]cron.update\[rq] file can also be used to ask -\f[B]crond\f[] to schedule a \[lq]named\[rq] cron job. +The "cron.update" file can also be used to ask \f[B]crond\f[] to +schedule a "named" cron job. To do this, append a line of the form: .IP .nf @@ -196,41 +191,48 @@ clio\ job1\ !job2 \f[] .fi .PP -to \[lq]cron.update\[rq]. -This request that user clio's job1 should be scheduled (waiting -first for the successful completion of any jobs named in job1's +to "cron.update". +This request that user clio\[aq]s job1 should be scheduled (waiting +first for the successful completion of any jobs named in job1\[aq]s AFTER= tag), and job2 should also be scheduled (without waiting for other jobs). See crontab(1) for more about tags and named jobs. .PP -The directory of per-user crontabs is re-parsed once every hour in -any case. -Any crontabs in the system directory (usually /etc/cron.d) are -parsed at the same time. +Instead of naming a file inside the directory, a single dot can be used +to name the directory as a whole. +So one can trigger a re\-read of all user\[aq]s crontabs by writing a +dot to "cron.update". +.PP +The directory of per\-user crontabs is re\-parsed once every hour in any +case. +Any crontabs in the system directory (usually /etc/cron.d) are parsed at +the same time. This directory can be used by packaging systems. -When you install a package foo, it might write its own foo-specific +When you install a package foo, it might write its own foo\-specific crontab to /etc/cron.d/foo. .PP -The superuser has a per-user crontab along with other users. +Package managers are encouraged to check whether dcron is installed, and +if so, write a dot to /etc/cron.d/cron.update after packages got +installed or removed, in order to more quickly trigger a re\-read of +those files. +.PP +The superuser has a per\-user crontab along with other users. It usually resides at /var/spool/cron/crontabs/root. .PP Users can only have a crontab if they have an entry in /etc/passwd; however they do not need to have login shell privileges. -Cron jobs are always run under /bin/sh; see crontab(1) for more -details. +Cron jobs are always run under /bin/sh; see crontab(1) for more details. .PP -Unlike \f[B]crontab\f[], the \f[B]crond\f[] program does not keep -open descriptors to crontab files while running their jobs, as this -could cause \f[B]crond\f[] to run out of descriptors. +Unlike \f[B]crontab\f[], the \f[B]crond\f[] program does not keep open +descriptors to crontab files while running their jobs, as this could +cause \f[B]crond\f[] to run out of descriptors. .SH SEE ALSO .PP \f[B]crontab\f[](1) .SH AUTHORS .PP -Matthew Dillon (dillon\@apollo.backplane.com): original -developer +Matthew Dillon (dillon\@apollo.backplane.com): original developer .PD 0 .P .PD -Jim Pryor (profjim\@jimpryor.net): current -developer +Jim Pryor (profjim\@jimpryor.net): current developer diff --git a/crontab.1 b/crontab.1 index 1e2f59f..abdf243 100644 --- a/crontab.1 +++ b/crontab.1 @@ -1,73 +1,70 @@ -.TH CRONTAB 1 "1 May 2011" +.TH "CRONTAB" "1" "1 May 2011" "" "" .SH NAME .PP -crontab - manipulate per-user crontabs (dillon's lightweight cron +crontab \- manipulate per\-user crontabs (dillon\[aq]s lightweight cron daemon) .SH SYNOPSIS .PP -\f[B]crontab file [-u user]\f[] - replace crontab from file +\f[B]crontab file [\-u user]\f[] \- replace crontab from file .PP -\f[B]crontab - [-u user]\f[] - replace crontab from stdin +\f[B]crontab \- [\-u user]\f[] \- replace crontab from stdin .PP -\f[B]crontab -l [-u user]\f[] - list crontab for user +\f[B]crontab \-l [\-u user]\f[] \- list crontab for user .PP -\f[B]crontab -e [-u user]\f[] - edit crontab for user +\f[B]crontab \-e [\-u user]\f[] \- edit crontab for user .PP -\f[B]crontab -d [-u user]\f[] - delete crontab for user +\f[B]crontab \-d [\-u user]\f[] \- delete crontab for user .PP -\f[B]crontab -c dir\f[] - specify crontab directory +\f[B]crontab \-c dir\f[] \- specify crontab directory .SH DESCRIPTION .PP -\f[B]crontab\f[] manipulates the per-user crontabs. +\f[B]crontab\f[] manipulates the per\-user crontabs. .PP -Generally the -e option is used to edit your crontab. -\f[B]crontab\f[] will use the editor specified by your EDITOR or -VISUAL environment variable (or /usr/bin/vi) to edit the crontab. +Generally the \-e option is used to edit your crontab. +\f[B]crontab\f[] will use the editor specified by your EDITOR or VISUAL +environment variable (or /usr/bin/vi) to edit the crontab. .PP -\f[B]crontab\f[] doesn't provide the kinds of protections that -programs like \f[B]visudo\f[] do against syntax errors and -simultaneous edits. -Errors won't be detected until \f[B]crond\f[] reads the crontab +\f[B]crontab\f[] doesn\[aq]t provide the kinds of protections that +programs like \f[B]visudo\f[] do against syntax errors and simultaneous +edits. +Errors won\[aq]t be detected until \f[B]crond\f[] reads the crontab file. -What \f[B]crontab\f[] does is provide a mechanism for users who may -not themselves have write privileges to the crontab folder to -nonetheless install or edit their crontabs. -It also notifies a running crond daemon of any changes to these -files. -.PP -Only users who belong to the same group as the \f[B]crontab\f[] -binary will be able to install or edit crontabs. -However it'll be possible for the superuser to install crontabs -even for users who don't have the privileges to install them -themselves. -(Even for users who don't have a login shell.) -Only the superuser may use the -u or -c switches to specify a -different user and/or crontab directory. -.PP -The superuser also has his or her own per-user crontab, saved as +What \f[B]crontab\f[] does is provide a mechanism for users who may not +themselves have write privileges to the crontab folder to nonetheless +install or edit their crontabs. +It also notifies a running crond daemon of any changes to these files. +.PP +Only users who belong to the same group as the \f[B]crontab\f[] binary +will be able to install or edit crontabs. +However it\[aq]ll be possible for the superuser to install crontabs even +for users who don\[aq]t have the privileges to install them themselves. +(Even for users who don\[aq]t have a login shell.) Only the superuser +may use the \-u or \-c switches to specify a different user and/or +crontab directory. +.PP +The superuser also has his or her own per\-user crontab, saved as /var/spool/cron/crontabs/root. .PP -Unlike other cron daemons, this crond/crontab package doesn't try -to do everything under the sun. -It doesn't try to keep track of user's preferred shells; that would -require special-casing users with no login shell. +Unlike other cron daemons, this crond/crontab package doesn\[aq]t try to +do everything under the sun. +It doesn\[aq]t try to keep track of user\[aq]s preferred shells; that +would require special\-casing users with no login shell. Instead, it just runs all commands using \f[C]/bin/sh\f[]. -(Commands can of course be script files written in any shell you -like.) +(Commands can of course be script files written in any shell you like.) .PP Nor does it do any special environment handling. -A shell script is better-suited to doing that than a cron daemon. -This cron daemon sets up only four environment variables: USER, -LOGNAME, HOME, and SHELL. +A shell script is better\-suited to doing that than a cron daemon. +This cron daemon sets up only four environment variables: USER, LOGNAME, +HOME, and SHELL. .PP Our crontab format is roughly similar to that used by vixiecron. -Individual fields may contain a time, a time range, a time range -with a skip factor, a symbolic range for the day of week and month -in year, and additional subranges delimited with commas. +Individual fields may contain a time, a time range, a time range with a +skip factor, a symbolic range for the day of week and month in year, and +additional subranges delimited with commas. Blank lines in the crontab or lines that begin with a hash (#) are ignored. -If you specify both a day in the month and a day of week, it will -be interpreted as the Nth such day in the month. +If you specify both a day in the month and a day of week, it will be +interpreted as the Nth such day in the month. .PP Some examples: .IP @@ -81,34 +78,31 @@ Some examples: 0\ */2\ *\ *\ *\ date #\ run\ every\ two\ hours\ between\ 11\ pm\ and\ 7\ am,\ and\ again\ at\ 8\ am -0\ 23-7/2,8\ *\ *\ *\ date +0\ 23\-7/2,8\ *\ *\ *\ date #\ run\ at\ 4:00\ am\ on\ January\ 1st 0\ 4\ 1\ jan\ *\ date #\ run\ every\ day\ at\ 11\ am,\ appending\ all\ output\ to\ a\ file -0\ 11\ *\ *\ *\ date\ >>\ /var/log/date-output\ 2>&1 +0\ 11\ *\ *\ *\ date\ >>\ /var/log/date\-output\ 2>&1 \f[] .fi .PP To request the last Monday, etc. -in a month, ask for the \[lq]6th\[rq] one. -This will always match the last Monday, etc., even if there are -only four Mondays in the month: +in a month, ask for the "5th" one. +This will always match the last Monday, etc., even if there are only +four Mondays in the month: .IP .nf \f[C] #\ run\ at\ 11\ am\ on\ the\ first\ and\ last\ Mon,\ Tue,\ Wed\ of\ each\ month -0\ 11\ 1,6\ *\ mon-wed\ date - -#\ run\ at\ noon\ on\ the\ fourth\ and\ last\ Friday\ of\ each\ month -0\ 12\ 4,6\ *\ fri\ date +0\ 11\ 1,5\ *\ mon\-wed\ date \f[] .fi .PP -When the fourth Monday in a month is also the last, this will match against -both the \[lq]4th\[rq] and the \[lq]6th\[rq] but the job is scheduled only -once. +When the fourth Monday in a month is the last, it will match against +both the "4th" and the "5th" (it will only run once if both are +specified). .PP The following formats are also recognized: .IP @@ -123,18 +117,18 @@ The following formats are also recognized: \f[] .fi .PP -The formats \@hourly, \@daily, \@weekly, \@monthly, and \@yearly -need to update timestamp files when their jobs have been run. +The formats \@hourly, \@daily, \@weekly, \@monthly, and \@yearly need to +update timestamp files when their jobs have been run. The timestamp files are saved as /var/spool/cron/cronstamps/user.jobname. -So for all of these formats, the cron command needs a jobname, -given by prefixing the command with \f[C]ID=jobname\f[]. -(This syntax was chosen to maximize the chance that our crontab -files will be readable by other cron daemons as well. -They might just interpret the ID=jobname as a command-line -environment variable assignment.) -.PP -There's also this esoteric option, whose usefulness will be +So for all of these formats, the cron command needs a jobname, given by +prefixing the command with \f[C]ID=jobname\f[]. +(This syntax was chosen to maximize the chance that our crontab files +will be readable by other cron daemons as well. +They might just interpret the ID=jobname as a command\-line environment +variable assignment.) +.PP +There\[aq]s also this esoteric option, whose usefulness will be explained later: .IP .nf @@ -146,34 +140,33 @@ explained later: \f[] .fi .PP -There's also a format available for finer-grained control of +There\[aq]s also a format available for finer\-grained control of frequencies: .IP .nf \f[C] -#\ run\ whenever\ it\[aq]s\ between\ 2-4\ am,\ and\ at\ least\ one\ day\ (1d) +#\ run\ whenever\ it\[aq]s\ between\ 2\-4\ am,\ and\ at\ least\ one\ day\ (1d) #\ has\ elapsed\ since\ this\ job\ ran -*\ 2-4\ *\ *\ *\ ID=job2\ FREQ=1d\ date +*\ 2\-4\ *\ *\ *\ ID=job2\ FREQ=1d\ date -#\ as\ before,\ but\ re-try\ every\ 10\ minutes\ (10m)\ if\ my_command +#\ as\ before,\ but\ re\-try\ every\ 10\ minutes\ (10m)\ if\ my_command #\ exits\ with\ code\ 11\ (EAGAIN) -*\ 2-4\ *\ *\ *\ ID=job3\ FREQ=1d/10m\ my_command +*\ 2\-4\ *\ *\ *\ ID=job3\ FREQ=1d/10m\ my_command \f[] .fi .PP -These formats also update timestamp files, and so also require -their jobs to be assigned IDs. +These formats also update timestamp files, and so also require their +jobs to be assigned IDs. .PP -Notice the technique used in the second example: jobs can exit with -code 11 to indicate they lacked the resources to run (for example, -no network was available), and so should be tried again after a -brief delay. -This works for jobs using either \@freq or FREQ=\&... formats; but -the FREQ=\&.../10m syntax is the only way to customize the length -of the delay before re-trying. +Notice the technique used in the second example: jobs can exit with code +11 to indicate they lacked the resources to run (for example, no network +was available), and so should be tried again after a brief delay. +This works for jobs using either \@freq or FREQ=... +formats; but the FREQ=.../10m syntax is the only way to customize the +length of the delay before re\-trying. .PP -Jobs can be made to \[lq]depend\[rq] on, or wait until AFTER other -jobs have successfully completed. +Jobs can be made to "depend" on, or wait until AFTER other jobs have +successfully completed. Consider the following crontab: .IP .nf @@ -183,15 +176,15 @@ Consider the following crontab: \f[] .fi .PP -Here, whenever job5 is up to be run, if job4 is scheduled to run -within the next 30 minutes (30m), job5 will first wait for it to -successfully complete. +Here, whenever job5 is up to be run, if job4 is scheduled to run within +the next 30 minutes (30m), job5 will first wait for it to successfully +complete. .PP -(What if job4 doesn't successfully complete? If job4 returns with -exit code EAGAIN, job5 will continue to wait until job4 is -retried\[em]even if that won't be within the hour. -If job4 returns with any other non-zero exit code, job5 will be -removed from the queue without running.) +(What if job4 doesn\[aq]t successfully complete? +If job4 returns with exit code EAGAIN, job5 will continue to wait until +job4 is retried\-\-\-even if that won\[aq]t be within the hour. +If job4 returns with any other non\-zero exit code, job5 will be removed +from the queue without running.) .PP Jobs can be told to wait for multiple other jobs, as follows: .IP @@ -201,54 +194,50 @@ Jobs can be told to wait for multiple other jobs, as follows: \f[] .fi .PP -The waiting job6 doesn't care what order job4 and job7 complete in. -If job6 comes up to be re-scheduled (an hour later) while an -earlier instance is still waiting, only a single instance of job6 -will remain in the queue. -It will have all of its \[lq]waiting flags\[rq] reset: so each of -job7 and job4 (supposing again that job4 would run within the next -1h) will again have to complete before job6 will run. +The waiting job6 doesn\[aq]t care what order job4 and job7 complete in. +If job6 comes up to be re\-scheduled (an hour later) while an earlier +instance is still waiting, only a single instance of job6 will remain in +the queue. +It will have all of its "waiting flags" reset: so each of job7 and job4 +(supposing again that job4 would run within the next 1h) will again have +to complete before job6 will run. .PP If a job waits on a \@reboot or \@noauto job, the target job being waited on will also be scheduled to run. -This technique can be used to have a common job scheduled as -\@noauto that several other jobs depend on (and so call as a -subroutine). -.PP -The command portion of a cron job is run with -\f[C]/bin/sh\ -c\ ...\f[] and may therefore contain any valid -Bourne shell command. -A common practice is to prefix your command with \f[B]exec\f[] to -keep the process table uncluttered. +This technique can be used to have a common job scheduled as \@noauto +that several other jobs depend on (and so call as a subroutine). +.PP +The command portion of a cron job is run with \f[C]/bin/sh\ \-c\ ...\f[] +and may therefore contain any valid Bourne shell command. +A common practice is to prefix your command with \f[B]exec\f[] to keep +the process table uncluttered. It is also common to redirect job output to a file or to /dev/null. -If you do not, and the command generates output on stdout or -stderr, that output will be mailed to the local user whose crontab -the job comes from. -If you have crontabs for special users, such as uucp, who can't +If you do not, and the command generates output on stdout or stderr, +that output will be mailed to the local user whose crontab the job comes +from. +If you have crontabs for special users, such as uucp, who can\[aq]t receive local mail, you may want to create mail aliases for them or adjust this behavior. (See crond(8) for details how to adjust it.) .PP -Whenever jobs return an exit code that's neither 0 nor 11 (EAGAIN), -that event will be logged, regardless of whether any stdout or -stderr is generated. -The job's timestamp will also be updated, and it won't be run again -until it would next be normally scheduled. -Any jobs waiting on the failed job will be canceled; they won't be -run until they're next scheduled. +Whenever jobs return an exit code that\[aq]s neither 0 nor 11 (EAGAIN), +that event will be logged, regardless of whether any stdout or stderr is +generated. +The job\[aq]s timestamp will also be updated, and it won\[aq]t be run +again until it would next be normally scheduled. +Any jobs waiting on the failed job will be canceled; they won\[aq]t be +run until they\[aq]re next scheduled. .SH TODO .PP -Ought to be able to have several crontab files for any given user, -as an organizational tool. +Ought to be able to have several crontab files for any given user, as an +organizational tool. .SH SEE ALSO .PP \f[B]crond\f[](8) .SH AUTHORS .PP -Matthew Dillon (dillon\@apollo.backplane.com): original -developer +Matthew Dillon (dillon\@apollo.backplane.com): original developer .PD 0 .P .PD -Jim Pryor (profjim\@jimpryor.net): current -developer +Jim Pryor (profjim\@jimpryor.net): current developer