I/O Redirection question

Tom Christiansen tchrist at convex.COM
Thu Apr 18 03:42:20 AEST 1991


>From the keyboard of browning at nas.nasa.gov (David S. Browning):
:I have a related question.  Is it possible, in csh, to redirect stdout
:and stderr to different files?  

    % (cmd > file.stdout) >& file.stderr

:Or to redirect stderr and not stdout?
:I know how to do it in sh/ksh, but not in csh.

No, that's not generally feasible, although if stdout is a tty, you can
redirect it to /dev/tty.  The True Shell solution of doing something to
stderr and leaving stdout alone can't be done in csh.

Consider this:

    cmd 2>file.stderr

cannot be done in the csh in a general way.  And let's say you want
to pipe stderr through a filter, leaving stdout inviolate.  It's even 
more impossible, although the True Shell does take a bit of staring
at to get used to.  

    $ 3>&1 (command_1 2>&1 1>&3 3>&- | command_2 3>&-)

More interesting contortions are also feasible.  Let's say I want to run
dd, send its stderr through a filter to throw out anticipated, leave its
stdout all alone, and have the whole thing return not the status from the
filter, but from dd.  In csh, you're so out of luck it's pitiful.  In a 
true shell, this works (believe it or not :-):

    #!/bin/sh
    dd_noise='^[0-9]+\+[0-9]+ records (in|out)$'
    exec 3>&1 status=`((dd if=/dev/rmt20 bs=64k 2>&1 1>&3 3>&- 4>&-; 
	      echo $? >&4) | egrep -v "$dd_noise" 1>&2 3>&- 4>&-) 4>&1` 
    exit $status  # or test and branch

You could call this "clean_dd" and use it this way:

    clean_dd > file || (echo dd error; exit 2) 

And still normal stderr stuff where you want it.

Three notes: 
    
1) The variable assignment is to make sure my special characters
   in the regexp survive the backticks.

2) I could never have done this without Maarten Litmath's help.

3) By ``True Shell'', I mean one that lets you manipulate 
   fd's as variables, pipe built-ins (like while) into commands, etc.


--tom



More information about the Comp.unix.shell mailing list