crontab & stderr discovery

Andrew Shore shore at adobe.UUCP
Mon Sep 30 08:26:28 AEST 1985


Here is a nice little trick I discovered for /usr/lib/crontab.
(All of the following is in 4.2BSD, I don't know how applicable
it is to other systems.)  I was always a little frustrated by
the loss of stderr output of cron-invoked shell scripts.  If
such scripts break, one hardly ever knows why or how.  A few
months ago, after reading Kernighan and Pike's excellent book
"The UNIX Programming Environment", and reviewing the /bin/sh
man page, I realized that the following /bin/sh syntax might
prove helpful:
	command args 1>outfile 2>&1
This tells /bin/sh to send stdout (fd==1) to "outfile" and to
make stderr (fd==2) a duplicate of fd 1.

I now have /usr/lib/crontab entries that look like:

1 0 * * * /bin/sh /usr/adm/script.sh 1>/usr/adm/script.log 2>&1

This works like a charm!  I get all the stderr output from the
shell executing script.sh and it's descendents.  I've never
seen this in anyone else's crontab.  Why?  Are there any
risks involved?  Am I the first person to discover this?

By the way, the man page for cron(8) lies.  It says that the
days are numbered 1-7 with 1=Monday.  The days are actually
numbered 0-6 with 0=Sunday.

Another gotcha that I have found is as follows.  Most systems
start up /etc/cron from /etc/rc.  cron and all crontab-entry
invoked processes are children of init (see cron(8) and
init(8)).  This can result in a few unexpected results now and
then, since init's environment is not the same as most
getty/login-invoked environments.  It is possible to create a
shell script with works just fine from some user's login, but
which breaks when run via crontab.  For example, scripts which
use the value of the environment variable USER will break,
since USER is undefined in init's environment. (One solution
might be to set and export USER and other common environment
variables to common and/or harmless values in /etc/rc!)


Now a question for all you gurus and wizards:

The cron(8) manual page says:
    "The sixth field is a string that is exe-
     cuted by the Shell at the specified times.  A percent char-
     acter in this field is translated to a new-line character.
     Only the first line (up to a % or end of line) of the com-
     mand field is executed by the Shell.  The other lines are
     made available to the command as standard input.

This seems to indicate that a line such as:

1 0 * * * /bin/sh /usr/adm/script.sh 1>/usr/adm/script.log 2>&1

wastes a shell; that it could be run as:

1 0 * * * /usr/adm/script.sh 1>/usr/adm/script.log 2>&1

Since the arguments are fed to a shell anyway.  Is this true?
Does /usr/adm/script.sh then have to be executable?
(It isn't now, I obviously haven't tried the alternatives.)

Hope you find my discovery helpful.
--Andy Shore
  Adobe Systems Incorporated
  
  {decwrl glacier sun}!adobe!shore
  adobe!shore at decwrl.ARPA



More information about the Comp.unix mailing list