pim@cti-software.nl (Pim Zandbergen) (10/08/90)
How can one redirect stderr to a command while leaving stdout unaffected ? -- Pim Zandbergen domain : pim@cti-software.nl CTI Software BV uucp : uunet!mcsun!hp4nl!ctisbv!pim Laan Copes van Cattenburch 70 phone : +31 70 3542302 2585 GD The Hague, The Netherlands fax : +31 70 3512837
coleman@sunny.DAB.GE.COM (Richard Coleman) (10/09/90)
-- In article <1990Oct8.165133.17187@cti-software.nl>, pim@cti-software.nl (Pim Zandbergen) writes: |> |> How can one redirect stderr to a command while leaving stdout unaffected ? For csh and bash try (command > temp1) >& temp2 For sh command 2> temp somebody else will have to handle ksh. Richard Coleman G.E. Simulation & Control Systems coleman@sunny.dab.ge.com
jik@athena.mit.edu (Jonathan I. Kamens) (10/09/90)
In article <6133@ge-dab.GE.COM>, coleman@sunny.DAB.GE.COM (Richard Coleman) writes: |> In article <1990Oct8.165133.17187@cti-software.nl>, pim@cti-software.nl (Pim Zandbergen) writes: |> |> How can one redirect stderr to a command while leaving stdout unaffected ? |> For csh and bash try (command > temp1) >& temp2 |> For sh command 2> temp The original poster asked how to redirect to a *command*. You've shown how to redirect to a *file*. In csh, one possible way to do it (when working at a tty) would be: (program > /dev/tty) |& command A similar approach will work in sh (and probably ksh), although there's probably some better way to do it with various hideous file descriptor reassignments (I don't use the bourne shell a lot, so I don't qualify to invent hideous file descriptor reassignments :-): (program > /dev/tty) 2>&1 | command -- Jonathan Kamens USnail: MIT Project Athena 11 Ashford Terrace jik@Athena.MIT.EDU Allston, MA 02134 Office: 617-253-8495 Home: 617-782-0710
pfalstad@flower.Princeton.EDU (Paul John Falstad) (10/09/90)
In article <1990Oct8.204053.15797@athena.mit.edu> jik@athena.mit.edu (Jonathan I. Kamens) writes: >|> |> How can one redirect stderr to a command while leaving stdout unaffected ? >A similar approach will work in sh (and probably ksh), although there's >probably some better way to do it with various hideous file descriptor >reassignments (I don't use the bourne shell a lot, so I don't qualify to >invent hideous file descriptor reassignments :-): > > (program > /dev/tty) 2>&1 | command They're not that hideous! In bash, sh, and (I'm fairly sure) ksh, you can do this and avoid the subshell: program 2>&1 >/dev/tty | command -- Are you nervy? Irritable? Depressed? Tired of life? Keep it up!
cpcahil@virtech.uucp (Conor P. Cahill) (10/09/90)
In article <1990Oct8.165133.17187@cti-software.nl> pim@cti-software.nl (Pim Zandbergen) writes: > >How can one redirect stderr to a command while leaving stdout unaffected ? Assuming you are asking this because you are using the c-shell (that doesn't support 2>) I will point you toward the comp.unix.questions FAQ posting (just posted in the last week) question number 16. -- Conor P. Cahill (703)430-9247 Virtual Technologies, Inc., uunet!virtech!cpcahil 46030 Manekin Plaza, Suite 160 Sterling, VA 22170
bob@wyse.wyse.com (Bob McGowen x4312 dept208) (10/09/90)
In article <6133@ge-dab.GE.COM> coleman@sunny.DAB.GE.COM (Richard Coleman) writes: > >-- >In article <1990Oct8.165133.17187@cti-software.nl>, pim@cti-software.nl (Pim Zandbergen) writes: >|> >|> How can one redirect stderr to a command while leaving stdout unaffected ? ^^^^^^^^ ^^^^^^^^^^^^ > > >For csh and bash try (command > temp1) >& temp2 >For sh command 2> temp > >somebody else will have to handle ksh. > The question was how to redirect to a command, not a file. You might think that something like 2| would work, but it doesn't (at least in sh, I have no ksh to try it on). I have tried several permutations of re-ordering file descriptors and trying to use new ones with the _exec- builtin but have had no success yet. Bob McGowan (standard disclaimer, these are my own ...) Product Support, Wyse Technology, San Jose, CA ..!uunet!wyse!bob bob@wyse.com
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (10/09/90)
In article <1990Oct8.204053.15797@athena.mit.edu> jik@athena.mit.edu (Jonathan I. Kamens) writes: > In csh, one possible way to do it (when working at a tty) would be: But who said there's a tty around? What if Pim wanted to pipe his output through yet another command? > A similar approach will work in sh (and probably ksh), although there's > probably some better way to do it with various hideous file descriptor > reassignments (I don't use the bourne shell a lot, so I don't qualify to > invent hideous file descriptor reassignments :-): I use the bourne shell a lot, so I guess I qualify. It isn't too hideous, though, if you write it clearly: ( exec 5>&1; exec 1>&2; exec 2>&5; foo ) | err-processor Even you :-) should be able to recognize the swap idiom there. Start from basic constructs like this and soon you'll be piping stdout and stderr through separate commands. Someday you may even learn to use multitee... [grin] ---Dan
henk@atcmp.nl (Henk M. Keller) (10/09/90)
In article <1990Oct8.165133.17187@cti-software.nl>, pim@cti-software.nl (Pim Zandbergen) writes: > > How can one redirect stderr to a command while leaving stdout unaffected ? The real solution in sh and ksh is to exchange stdout and stderr: command_1 3>&1 1>&2 2>&3 3>&- | command_2 Well, some comments may be needed :-) (a) 3>&1 File descriptor 3 now is an 'alias' for 1 (original stdout) (b) 1>&2 File descr. 1 now is an 'alias' for 2 (original stderr) (c) 2>&3 File descr. 2 now is an 'alias' for 3 which still is an alias for the original stdout (d) 3>&- File descr. 3 is closed as it is no longer needed Net effect: File descriptor 1 (stdout) is connected to the original stderr (b) File descriptor 2 (stderr) is connected to the original stdout (c) For C writers amongst you: 3>&1 will probably be implemented as close(3); /* To ensure 3 is free */ fcntl(1, F_DUPFD, 3); /* Returns lowest possible */ /* 'dup'ed file descr. >= 3 */ /-------------------------------------------------------+ / Henk Keller AT Computing bv | | Teleph.: +31 80 566880 P.O. Box 1428 | | Fax: +31 80 555887 6501 BK Nijmegen | | Email: henk@atcmp.nl The Netherlands | | mcsun!hp4nl!kunivv1!atcmpe!henk | | | | -- do not fold -- | +---------------------------------------------------------+
rick@tetrauk.UUCP (Rick Jones) (10/09/90)
In article <3207@idunno.Princeton.EDU> pfalstad@flower.Princeton.EDU (Paul John Falstad) writes: >In article <1990Oct8.204053.15797@athena.mit.edu> jik@athena.mit.edu (Jonathan I. Kamens) writes: >>|> |> How can one redirect stderr to a command while leaving stdout unaffected ? > >In bash, sh, and (I'm fairly sure) ksh, you can do this and avoid the >subshell: > >program 2>&1 >/dev/tty | command In sh, file descriptor re-directions are evaluated left to right, so you can even swap stdout & stderr with a little care & avoid /dev/tty if you want: program 3>&2 2>&1 >&3 | command I think this should work in ksh, but doesn't seem to in my version - a buglet? I can't speak for bash as I don't use it. -- Rick Jones The definition of atomic: Tetra Ltd. from the Greek meaning "indivisible" Maidenhead, Berks, UK So what is: rick@tetrauk.uucp an atomic explosion?
maart@cs.vu.nl (Maarten Litmaath) (10/10/90)
In article <668@atcmpe.atcmp.nl>, henk@atcmp.nl (Henk M. Keller) writes: )In article <1990Oct8.165133.17187@cti-software.nl>, ) pim@cti-software.nl (Pim Zandbergen) writes: )> )> How can one redirect stderr to a command while leaving stdout unaffected ? ) )The real solution in sh and ksh is to exchange stdout and stderr: ) ) command_1 3>&1 1>&2 2>&3 3>&- | command_2 But that still does _not_ answer Pim's question! He said: `... while leaving stdout _unaffected_' (emphasis added). In Henk's example stdout is dup(2)ed to stderr. So: exec 3>&1 command_1 2>&1 1>&3 3>&- | command_2 3>&- exec 3>&- Or: 3>&1 (command_1 2>&1 1>&3 3>&- | command_2 3>&-) # yes Virginia, that's correct Don't forget to close the extra descriptor, or you'll get screwed one day. -- "the C shell is flakier than a snowstorm." (Guy Harris)
das@lanai.cs.ucla.edu (David Smallberg) (10/10/90)
In article <5069:Oct903:10:1390@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >In article <1990Oct8.204053.15797@athena.mit.edu> jik@athena.mit.edu (Jonathan I. Kamens) writes: >> A similar approach will work in sh (and probably ksh), although there's >> probably some better way to do it with various hideous file descriptor >> reassignments. >... > ( exec 5>&1; exec 1>&2; exec 2>&5; foo ) | err-processor Unnecessary subshell creation. This works under sh and ksh: { pgm1 2>&1 1>&3 | pgm2 ;} 3>&1 Explanation: Suppose stdout originally goes to <stdout> (whether that be a file, the terminal, or whatever). Outside the { }, we open file descriptor 3 to also go to <stdout>. pgm2's stdout is unaffected, so it will go to <stdout>. The "|" at first causes pgm1's stdout to go into the pipe. The "2>&1" causes pgm1's stderr to also go into the pipe. The "1>&3" causes pgm1's stdout to no longer go into the pipe, but into file descriptor 3, which goes to <stdout>. Result: pgm1's stderr goes into the pipe. pgm1's stdout and pgm2's stdout go to the original stdout destination. pgm2's stderr goes to the original stderr destination. Now only pgm1's stderr goes into the pipe. -- -- David Smallberg, das@cs.ucla.edu, ...!{uunet,ucbvax,rutgers}!cs.ucla.edu!das
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (10/10/90)
In article <668@atcmpe.atcmp.nl> henk@atcmp.nl (Henk M. Keller) writes: > 3>&1 will probably be implemented as > close(3); /* To ensure 3 is free */ > fcntl(1, F_DUPFD, 3); /* Returns lowest possible */ > /* 'dup'ed file descr. >= 3 */ Or dup2(1,3). ---Dan
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (10/10/90)
In article <39936@shemp.CS.UCLA.EDU> das@lanai.cs.ucla.edu (David Smallberg) writes: > In article <5069:Oct903:10:1390@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: > > ( exec 5>&1; exec 1>&2; exec 2>&5; foo ) | err-processor > Unnecessary subshell creation. [snif] I feel insulted. No, it does *not* create an extra shell. Perhaps you should test these things before you post. This is a good point to remember: certain builtins, such as exec, correspond directly to system calls between fork() and exec(), and current shells understand this perfectly. There's also nothing wrong with using () instead of {} at the beginning of a pipe; the shell internally surrounds each component of the pipe with parentheses and then removes redundant levels. (Well, sort of, but you get the idea.) In fact, {} wastes time, as it requires a semicolon at the end---something that whoever maintains your script might later forget. ---Dan
tif@doorstop.austin.ibm.com (Paul Chamberlain) (10/10/90)
In article <3002@wyse.wyse.com> bob@wyse.UUCP (Bob McGowen x4312 dept208) writes: >In article <1990Oct8.165133.17187@cti-software.nl>, pim@cti-software.nl writes: >> How can one redirect stderr to a command while leaving stdout unaffected ? >The question was how to redirect to a command, not a file. You might think >that something like 2| would work, but it doesn't (at least in sh, I have >no ksh to try it on). > >I have tried several permutations of re-ordering file descriptors and trying >to use new ones with the _exec- builtin but have had no success yet. Just thought I'd take a stab at it. There may be a better way. I use Korn Shell. $ echo now is the time > xx $ rm -f zz $ ( cat zz xx 2>&1 1>&3 | od -c ) 3>&1 now is the time 0000000 c a t : c a n n o t o p e n 0000020 z z \n 0000024 Paul Chamberlain | I do NOT represent IBM. tif@doorstop, sc30661 at ausvm6 512/838-7008 | ...!cs.utexas.edu!ibmaus!auschs!doorstop.austin.ibm.com!tif
das@lanai.cs.ucla.edu (David Smallberg) (10/10/90)
Dan Bernstein writes: >In article <39936@shemp.CS.UCLA.EDU> das@lanai.cs.ucla.edu (David Smallberg) writes: >> In article <5069:Oct903:10:1390@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >> > ( exec 5>&1; exec 1>&2; exec 2>&5; foo ) | err-processor >> Unnecessary subshell creation. > >[snif] I feel insulted. No, it does *not* create an extra shell. Perhaps >you should test these things before you post. My apologies. It's been a while since I've done this kind of stuff under sh, but I remember that at one time (could be many years ago) there really was an extra process creation. As recently as a few months ago, I reported a situation in which ksh88d could be clever enough to do an exec without a fork, but wasn't -- I haven't checked yet to see if ksh88e "fixes" it. So I guess I trust the shells to do the clever thing less often than they deserve to be trusted. >This is a good point to remember: certain builtins, such as exec, >correspond directly to system calls between fork() and exec(), and >current shells understand this perfectly. That's certainly true for builtins. But as I noted above, even current shells don't always "understand" some constructs perfectly. (By "understand", I mean understand to the point where a fairly obvious unnecessary fork can be eliminated.) -- -- David Smallberg, das@cs.ucla.edu, ...!{uunet,ucbvax,rutgers}!cs.ucla.edu!das
les@chinet.chi.il.us (Leslie Mikesell) (10/11/90)
In article <5069:Oct903:10:1390@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >But who said there's a tty around? What if Pim wanted to pipe his output >through yet another command? > > ( exec 5>&1; exec 1>&2; exec 2>&5; foo ) | err-processor > >Even you :-) should be able to recognize the swap idiom there. Start >from basic constructs like this and soon you'll be piping stdout and >stderr through separate commands. Someday you may even learn to use >multitee... [grin] Or FIFO's (which might even be available on his machine...) /etc/mknod /tmp/fifo$$ p err-processor < /tmp/fifo$$ & command 2>/tmp/fifo$$ | output_processor rm /tmp/fifo$$ Straightforward enough, and err-processor would not even be required to have a common parent with the rest of the programs if they have some way of determining the name to use. Les Mikesell les@chinet.chi.il.us
emanuele@overlf.UUCP (Mark A. Emanuele) (10/14/90)
In article <1990Oct8.165133.17187@cti-software.nl>, pim@cti-software.nl (Pim Zandbergen) writes: > > How can one redirect stderr to a command while leaving stdout unaffected ? I'm not 100% sure but logically this should work. command1 2>tempfile & tail -f tempfile | command2 the only problem I think would be that the tail -f would never end. another solution: again I'm not sure but here goes: command1 2|command2 I have not tried either of these . let me know if they work. -- Mark A. Emanuele V.P. Engineering Overleaf, Inc. 500 Route 10 Ledgewood, NJ 07852-9639 attmail!overlf!emanuele (201) 927-3785 Voice (201) 927-5781 fax emanuele@overlf.UUCP