jc@minya.UUCP (John Chambers) (10/18/87)
Hi, folks. Here's my shell puzzle of the day. We all learn in our first hour of Unix lessons how to redirect input and output of any command that is started by a shell. What I'd like to know is: Is there a "right" way to tell the shell to redirect the output of ALL subsequent commands to a file? My motivation is as follows. Like some of you, I have written scripts that aren't, let's say, totally perfect the first time. Something really hard to debug is a script that works fine when I run it, but doesn't work so fine when someone else (like cron, maybe) runs it. What I'd like to do is to arrange it so that the program redirects its own output to an "audit trail" for my perusal. I don't want to bother the poor user with all the garbage output; I'd rather have it done quietly, with no fuss or bother. For C programs, this is easy: close(1); open("/aud/fubar",2); close(2); dup(1); for instance. For scripts, it's not so easy. What I find myself doing a lot is having one script, "foo", that looks like: exec bar >/aud/foo 2>&1 with the real work in the "bar" script. This works just fine, but it seems a rather clumsy approach. I have two scripts where one would do, the "foo" script occupies a whole 1K disk block (and an inode and a directory entry) unnecessarily, and the kernel is bothered with a totally unneeded exec. What I'd like is to write the "bar" script so that it starts with something equivalent to the above four lines of C. But I can't find anything in the sh(1) pages, or in the shell teaching documents, that explains how to do file opens and closes in the shell language. Any hints? Or is this just a deficiency in the language that I'll have to learn to live with? I mean, it's not a big deal to have one script exec another. It just seems like a silly kludge that wastes my and the machine's time and makes the code look awkward. That's unaesthetic. -- John Chambers <{adelie,ima,maynard,mit-eddie}!minya!{jc,root}> (617/484-6393)
c188-bl@katerina.uucp (Steven Brian McKechnie Sargent) (10/19/87)
Try the "exec" command of the Shell. The full syntax is exec [command] [redirections] [Redirections] is optional, in which case [command] runs with the default I/O; what most people don't know is that [command] is also optional, in which case [redirections] are applied to the running shell. So if you say words like exec 2>thump all standard-error redirections go to a file named "thump." Saying words like exec 14 >&2 exec 2>thump will save the old value of 2 in 14, redirect 2 into "thump." Later you can undo this with exec 2>&14 exec 14>&- which restores 2 from 14 and then closes 14. All this is documented in sh(1), but so tersely that you can skip right over it and never notice. S.
dave@lsuc.UUCP (10/20/87)
In article <289@minya.UUCP>, jc@minya.UUCP (John Chambers) writes: > Is there a "right" way > to tell the shell to redirect the output of ALL subsequent commands to a > file? We ran into this when running stuff at startup from /etc/rc (on a v7-based system, not that it matters). I found all those ">/dev/console"s a bit ugly. Mark Brader, {lsuc,sq}!msb suggested: exec sh <<'_UNTIL_THE_END_OF_THIS_FILE_' >/dev/console 2>&1 which we've been using for years now. Note that sh doesn't ever need to find the _UNTIL_etc. string; if it encounters EOF it exits happily. David Sherman The Law Society of Upper Canada Toronto -- { uunet!mnetor pyramid!utai decvax!utcsri ihnp4!utzoo } !lsuc!dave Pronounce it ell-ess-you-see, please...
allbery@ncoast.UUCP (Brandon Allbery) (10/23/87)
As quoted from <289@minya.UUCP> by jc@minya.UUCP (John Chambers): +--------------- | Hi, folks. Here's my shell puzzle of the day. We all learn in our first | hour of Unix lessons how to redirect input and output of any command that | is started by a shell. What I'd like to know is: Is there a "right" way | to tell the shell to redirect the output of ALL subsequent commands to a | file? +--------------- Nonintuitive, ugly, and while it's documented it took me years to figure out that this was what they meant: Start your script with "exec >file 2>&1". (Note that you don't actually exec anything, all you give are the redirections.) -- Brandon S. Allbery necntc!ncoast!allbery@harvard.harvard.edu {{harvard,mit-eddie}!necntc,well!hoptoad,sun!mandrill!hal}!ncoast!allbery
ignatz@chinet.UUCP (Dave Ihnat) (10/24/87)
As many people have provided correct answers to the original redirection query (i.e., to do something like "exec >fud 2>&1", I won't say it here... But nobody gave the fellow a little freebie that I don't see many other people using; that is, you can open other files that way, too: exec 3>fred exec 4>charlie Then, later, you can have specific output in the script go to these files via, for instance, command >&4 Arcane, yes; but useful at times. The biggest advantage is to open one for input ("exec 4<foo"); subsequent "read INLINE <&4" will retain their current positions in the file, unlike 'line'. Note that you can and *will* interact with any programs you're running in the script, since you're opening file descriptors... -- Dave Ihnat ihnp4!homebru!ignatz || ihnp4!chinet!ignatz (w) (312) 882-4673