377 lines
14 KiB
HTML
377 lines
14 KiB
HTML
<!--startcut ======================================================= -->
|
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
|
<html>
|
|
<head>
|
|
<META NAME="generator" CONTENT="lgazmail v1.3D.j">
|
|
<TITLE>The Answer Guy 54: Cron</TITLE>
|
|
</HEAD><BODY BGCOLOR="#FFFFFF" TEXT="#000000"
|
|
LINK="#3366FF" VLINK="#A000A0">
|
|
<!-- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -->
|
|
<P> <hr>
|
|
<!-- *** BEGIN navbar *** :::::::::::::::::::::::::::::::::::::::::::::::: -->
|
|
<p align="center">
|
|
<A HREF="../lg_bytes54.html"><IMG ALT="[ Prev ]"
|
|
SRC="../../gx/navbar/prev.jpg"
|
|
WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A>
|
|
<IMG ALT="" SRC="../../gx/navbar/left.jpg"
|
|
WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom" >
|
|
<A HREF="../index.html"><IMG ALT="[ Table of Contents ]"
|
|
SRC="../../gx/navbar/toc.jpg"
|
|
WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A>
|
|
<A HREF="../../index.html"><IMG ALT="[ Front Page ]"
|
|
SRC="../../gx/navbar/frontpage.jpg"
|
|
WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A>
|
|
<A HREF="../../faq/index.html"><IMG ALT="[ FAQ ]"
|
|
SRC="../../gx/navbar/faq.jpg"
|
|
WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A>
|
|
<IMG ALT="" SRC="../../gx/navbar/right.jpg"
|
|
WIDTH="15" HEIGHT="45" ALIGN="bottom" >
|
|
<A HREF="../lg_tips54.html"><IMG ALT="[ Next ]"
|
|
SRC="../../gx/navbar/next.jpg"
|
|
WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A>
|
|
<!-- *** END navbar *** :::::::::::::::::::::::::::::::::::::::::::::::::: -->
|
|
</p>
|
|
<P> <hr> <P>
|
|
<!-- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -->
|
|
<center>
|
|
<H1><A NAME="answer">
|
|
<img src="../../gx/dennis/qbubble.gif" alt="(?)"
|
|
border="0" align="middle">
|
|
<font color="#B03060">The Answer Guy</font>
|
|
<img src="../../gx/dennis/bbubble.gif" alt="(!)"
|
|
border="0" align="middle">
|
|
</A></H1>
|
|
<BR>
|
|
<H4>By James T. Dennis,
|
|
<a href="mailto:linux-questions-only@ssc.com">linux-questions-only@ssc.com</a><BR>
|
|
LinuxCare,
|
|
<A HREF="http://www.linuxcare.com/">http://www.linuxcare.com/</A>
|
|
</H4>
|
|
</center>
|
|
|
|
<p><hr><p>
|
|
<!-- endcut ======================================================= -->
|
|
<!-- begin 14 -->
|
|
<H3 align="left"><img src="../../gx/dennis/qbubble.gif"
|
|
height="50" width="60" alt="(?) " border="0"
|
|
>Cron</H3>
|
|
|
|
|
|
<p><strong>From Drew Jackson on Sun, 14 May 2000
|
|
</strong></p>
|
|
<!-- ::
|
|
Cron
|
|
~~~~
|
|
:: -->
|
|
<P><STRONG>
|
|
Dear sir:
|
|
</STRONG></P>
|
|
<P><STRONG><BLOCKQuote>
|
|
I have recently installed an anti-virus software program that is
|
|
</BLOCKQuote></STRONG></P>
|
|
<P><STRONG>
|
|
executed from the command-line. I would like for this service to run at
|
|
regular intervals. (i.e. every 2 hours)
|
|
</STRONG></P>
|
|
<P><STRONG>
|
|
I am using a <A HREF="http://www.redhat.com/">Red Hat</A> 5.2 based platform without GUI support.
|
|
</STRONG></P>
|
|
<P><STRONG>
|
|
Thank you for your time and effort.
|
|
</STRONG></P>
|
|
<P><STRONG>
|
|
Sincerely,
|
|
Drew Jackson
|
|
</STRONG></P>
|
|
<BLOCKQUOTE><IMG SRC="../../gx/dennis/bbub.gif" ALT="(!)"
|
|
HEIGHT="28" WIDTH="50" BORDER="0"
|
|
>
|
|
Short answer: use cron (the UNIX/Linux scheduling daemon/service).
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
The easiest way to do this would be use a text entry to
|
|
the <TT>/etc/crontab</TT> file that would look something like:
|
|
</BLOCKQUOTE>
|
|
|
|
<blockquote><pre>0 */2 * * * root /root/bin/vscan.sh
|
|
</pre></blockquote>
|
|
<BLOCKQUOTE>
|
|
(Obviously you'd replace the filename <TT>/root/bin/vscan.sh</TT> with
|
|
the actual command you need to run, or create a vscah.sh
|
|
shell script to contain all of the commands that you want
|
|
to run).
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
This table consist of the following fields: minute, hour,
|
|
day of month, month, day of week, user, command. Each of
|
|
the first five fields is filled with numerics, from one or
|
|
zero. So the minutes field is 0-59, from the first to the
|
|
last minute within any hour. The "*" character means "every"
|
|
(like in filename globbing, or "wildcard matching"). The
|
|
hours are 0-23, the dates are from 1-31, etc. The syntax of
|
|
this file allows one to specify ranges (9-17 for 9:00 am to
|
|
5:00 pm for example), lists (1,15 for the first and fifteenth
|
|
--- presumably one you'd use for dates within a month), and
|
|
modulo patterns (such as the one in my example, which means
|
|
"ever other" or "ever even"). So, to do something every
|
|
fifteen minutes of every other day of every month I'd
|
|
use a pattern like: '<tt>*/4 * */2 * * user command</tt>'.
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
The day of week and the months can use symbolic names
|
|
and English abbreviations in the most common versions
|
|
'cron' utility (by Paul Vixie) that are included with
|
|
Linux distributions.
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
You can read the crontab(5) man page for details.
|
|
Note that there is a 'crontab' command which has
|
|
its own man page in section one. Since section
|
|
one (user commands) is generally searched first
|
|
--- you have to use a command like: 'man 5 crontab'
|
|
to read the section five manual page on the
|
|
topic. (Section five is devoted to text file
|
|
formats --- documenting the syntax of many UNIX
|
|
configuration files).
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
This system is pretty flexible but cannot handle some
|
|
date patterns that we intuitively use through natural
|
|
language. For example: 2nd Tuesday of the month
|
|
doesn't translate directly into any pattern in
|
|
a crontab. Generally the easiest way to handle that
|
|
is to have a crontab entry that goes off the minimal
|
|
number of times that <EM>can</EM> be expressed in crontab
|
|
patters, and have a short stub of shell code that
|
|
checks for the additional conditions.
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
For example, to get some activity on the second
|
|
Tuesday of the month you might use a contab entry
|
|
like:
|
|
</BLOCKQUOTE>
|
|
|
|
<blockquote><pre>* * * * 2 joe /home/joe/bin/2ndtuesday.sh
|
|
</pre></blockquote>
|
|
<BLOCKQUOTE>
|
|
which runs every Tuesday. If we used a pattern
|
|
like:
|
|
</BLOCKQUOTE>
|
|
|
|
<blockquote><pre>* * 7-13 * 2 joe /home/joe/bin/2ndtuesday.sh
|
|
</pre></blockquote>
|
|
<BLOCKQUOTE>
|
|
... our command would run on every Tuesday <EM>and</EM> on
|
|
each of the days of the second week of the month
|
|
(from the 7th through the 13th). This is NOT what
|
|
we want. So we use the former pattern and have a
|
|
line near the beginning of our shell script that
|
|
looks something like:
|
|
</BLOCKQUOTE>
|
|
|
|
<blockquote><pre>#!/bin/bash
|
|
|
|
# Which week is this?
|
|
weeknum=$[ $(date +%e) / 7 + 1 ]
|
|
## returns 1 through 5
|
|
[ "$weeknum" == 2 ] || exit 0
|
|
|
|
# Rest of script below this line:
|
|
|
|
</pre></blockquote>
|
|
<BLOCKQUOTE>
|
|
Of course that could be shortened to one expression like:
|
|
</BLOCKQUOTE>
|
|
|
|
<blockquote><pre>[ "$[ $(date +%e) / 7 + 1 ]" == 2 ] || exit 0
|
|
</pre></blockquote>
|
|
<BLOCKQUOTE>
|
|
... which works under 'bash' (the default Linux command
|
|
shell) and should would under any recent version of ksh
|
|
(the Korn shell). That might need adjustment to run
|
|
under other shells. This also assumes that we have
|
|
the FSF GNU 'date' command (which is also the default
|
|
under Linux).
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
Of course, if you were going to do this more than a few
|
|
times we'd be best off writing one script that used
|
|
this logic can calling that in all of our crontab entries
|
|
that needed it. For example we could have a script
|
|
named 'week' that might look something like:
|
|
</BLOCKQUOTE>
|
|
|
|
<blockquote><pre>#!/bin/bash
|
|
## Week
|
|
## Conditionally execute a command if it is issued
|
|
## during a given week of the month.
|
|
## weeks are numbered 1 through 5
|
|
|
|
[ $# -ge 2 ] || {
|
|
echo "$0 requires least two args: week number and command" 1>&2
|
|
exit 1
|
|
}
|
|
|
|
[ "$(( $1 + 0 ))" == "$1" ] &> /dev/null || {
|
|
echo "$0: first argument must be a week number" 1>&2
|
|
exit 1
|
|
}
|
|
|
|
[ "$[ $(date +%e) / 7 + 1 ]" == "$1" ] || exit 0
|
|
shift
|
|
eval $@
|
|
</pre></blockquote>
|
|
<BLOCKQUOTE>
|
|
... or something like that.
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
(syntax notes about this shell script: '[' is an alias for the
|
|
'test' command; '$#' is a shell scripting token that means
|
|
"the number of arguments"; '||' is a shell "conditional execution
|
|
operator" (means, if the last thing returned an error code,
|
|
do this); '1>&2' is a shell redirection idiom that means "print
|
|
this as an error message"; '$[ ... ]' and '$(( ... ))' enclose
|
|
arithmetic expressions (a bash/ksh extension); '$@' is all
|
|
of our (remaining) arguments; and the braces enclose groups of
|
|
commands, so my error messages and exit commands are taken
|
|
together in the cases I've shown here).
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
So this shell script basically translates to:
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE><BLOCKQuote>
|
|
If there aren't at least 2 command line arguments here,
|
|
complain and exit. If the first argument isn't a number
|
|
(adding 0 to any number should yield the same number)
|
|
then complain and exit. If the week number of today's
|
|
date doesn't match the in the first argument then
|
|
just exit (no complain). Otherwise, forget that first
|
|
argument and treat the rest of the arguments as a
|
|
command.
|
|
</BLOCKQuote></BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
(Note: cron automatically sends the owner of a job
|
|
e-mail if the command exits with a non-zero (error) value
|
|
or if it produces any output. Normally people write
|
|
the cron job scripts to avoid generating any normal output
|
|
<TT>---</TT> they either pipe the output into an e-mail, redirect
|
|
it to <TT>/dev/null</TT> or to some custom log file; and/or possibly
|
|
add 'logger' commands to send messages to the system logging
|
|
services ('syslog'). E-mail from 'cron' consists of some
|
|
diagnostics information and any output from the job).
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
In some fairly rare cases it would be necessary to wrap
|
|
the target command, or parts of it in single quotes to get it
|
|
to work as desired. Those involve subtleties of shell syntax
|
|
that are way beyond the task at hand.
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
A more elaborate version of that shell script might allow
|
|
one to have a first argument that consisted of more than
|
|
one week number. The easiest way to do that would be to
|
|
require that multiple week numbers be quoted and separated
|
|
with spaces. Then we'd call it with a command like
|
|
'week "1 3" $cmd' (note the double quotes around 1 and 3).
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
That would add about five lines to my script. Anyway,
|
|
I don't feel like it right now so it's left as an exercise
|
|
to the reader.
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
Anyway, 'cron' is one of the most basic UNIX services. It
|
|
and the related 'at' command (schedule "one time" events)
|
|
are vital system administration and user tools. You should
|
|
definitely read up on them in any good general book on using
|
|
or administering UNIX or Linux. (I personally think that they
|
|
are woefully <EM>underused</EM> judging from the number of "temporary"
|
|
kludges that I have found on systems. Hint: every time you
|
|
do something that's supposed to be a "temporary" change to
|
|
your system --- submit an 'at' job to remind you when you
|
|
should look at it again; maybe to remove it).
|
|
</BLOCKQUOTE>
|
|
<BLOCKQUOTE>
|
|
BTW: I'd suggest that you seriously consider upgrading to a
|
|
newer version of Linux. Red Hat 5.2 was one of the most stable
|
|
releases of Red Hat. However, there have been many security
|
|
enhancements to many of the packages therein over the years.
|
|
</BLOCKQUOTE>
|
|
|
|
<!-- sig -->
|
|
|
|
|
|
<!-- end 14 -->
|
|
<!--startcut ======================================================= -->
|
|
<P> <hr> </p>
|
|
<H5 align="center"><a href="http://www.linuxgazette.com/copying.html"
|
|
>Copyright ©</a> 2000, James T. Dennis
|
|
<BR>Published in <I>The Linux Gazette</I> Issue 54 June 2000</H5>
|
|
<H6 ALIGN="center">HTML transformation by
|
|
<A HREF="mailto:star@tuxtops.com">Heather Stern</a> of
|
|
Tuxtops, Inc.,
|
|
<A HREF="http://www.tuxtops.com/">http://www.tuxtops.com/</A>
|
|
</H6>
|
|
<P> <hr>
|
|
<!-- begin tagnav ::::::::::::::::::::::::::::::::::::::::::::::::::-->
|
|
<p align="center">
|
|
<IMG ALT="" SRC="../../gx/navbar/left.jpg"
|
|
WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="middle" border="0">
|
|
<A HREF="../lg_answer54.html"
|
|
><IMG SRC="../../gx/dennis/answertoc.jpg" align="middle"
|
|
ALT="[ Answer Guy Current Index ]" border="0"></A>
|
|
<A HREF="../lg_answer54.html#greeting"><img align="middle"
|
|
src="../../gx/dennis/smily.gif" alt="greetings" border="0"></A>
|
|
<A HREF="1.html">1</A>
|
|
<A HREF="2.html">2</A>
|
|
<A HREF="3.html">3</A>
|
|
<A HREF="4.html">4</A>
|
|
<A HREF="5.html">5</A>
|
|
<A HREF="6.html">6</A>
|
|
<A HREF="7.html">7</A>
|
|
<A HREF="8.html">8</A>
|
|
<A HREF="9.html">9</A>
|
|
<A HREF="10.html">10</A>
|
|
<A HREF="11.html">11</A>
|
|
<A HREF="12.html">12</A>
|
|
<A HREF="13.html">13</A>
|
|
<A HREF="14.html">14</A>
|
|
<A HREF="15.html">15</A>
|
|
<A HREF="16.html">16</A>
|
|
<A HREF="17.html">17</A>
|
|
<A HREF="18.html">18</A>
|
|
<A HREF="../../tag/kb.html"
|
|
><IMG SRC="../../gx/dennis/answerpast.jpg" align="middle"
|
|
ALT="[ Index of Past Answers ]" border="0"></A></td>
|
|
<IMG ALT="" SRC="../../gx/navbar/right.jpg" align="middle"
|
|
WIDTH="14" HEIGHT="45" BORDER="0">
|
|
</p>
|
|
<!-- end tagnav ::::::::::::::::::::::::::::::::::::::::::::::::::::-->
|
|
<P> <hr>
|
|
<!-- *** BEGIN navbar *** :::::::::::::::::::::::::::::::::::::::::::::::: -->
|
|
<p align="center">
|
|
<A HREF="../lg_bytes54.html"><IMG ALT="[ Prev ]"
|
|
SRC="../../gx/navbar/prev.jpg"
|
|
WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A>
|
|
<IMG ALT="" SRC="../../gx/navbar/left.jpg"
|
|
WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom" >
|
|
<A HREF="../index.html"><IMG ALT="[ Table of Contents ]"
|
|
SRC="../../gx/navbar/toc.jpg"
|
|
WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A>
|
|
<A HREF="../../index.html"><IMG ALT="[ Front Page ]"
|
|
SRC="../../gx/navbar/frontpage.jpg"
|
|
WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A>
|
|
<A HREF="../../faq/index.html"><IMG ALT="[ FAQ ]"
|
|
SRC="../../gx/navbar/faq.jpg"
|
|
WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A>
|
|
<IMG ALT="" SRC="../../gx/navbar/right.jpg"
|
|
WIDTH="15" HEIGHT="45" ALIGN="bottom" >
|
|
<A HREF="../lg_tips54.html"><IMG ALT="[ Next ]"
|
|
SRC="../../gx/navbar/next.jpg"
|
|
WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A>
|
|
<!-- *** END navbar *** :::::::::::::::::::::::::::::::::::::::::::::::::: -->
|
|
</p>
|
|
<!-- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -->
|
|
</BODY></HTML>
|
|
<!--endcut ========================================================= -->
|