Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/18/84; site adobe.UUCP Path: utzoo!linus!decvax!decwrl!Glacier!adobe!shore From: shore@adobe.UUCP (Andrew Shore) Newsgroups: net.unix Subject: crontab & stderr discovery Message-ID: <704@adobe.UUCP> Date: Sun, 29-Sep-85 18:26:28 EDT Article-I.D.: adobe.704 Posted: Sun Sep 29 18:26:28 1985 Date-Received: Wed, 2-Oct-85 20:59:23 EDT Reply-To: shore@adobe.UUCP (Andrew Shore) Organization: Adobe Systems, Palo Alto Lines: 68 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@decwrl.ARPA Brought to you by Super Global Mega Corp .com