[comp.unix.shell] I/O Redirection question

dwsmith@loki.arc.NASA.GOV (David Smith) (04/11/91)

I have a question regarding I/O redirection.  I have a program in which
writes to stdout and stderr.  I have redirected both of these to a file.

Now comes the problem.  I need to capture stdout in a file along with
stderr, but I also need stdout to go to the terminal for prompting of
input.  Is this possible?  If so, how does one do this?

Answers may be mailed to me directly or you may post responses.  A solution
in for the csh, sh, ksh are all acceptable.

Thank you,


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  David W. Smith
  NASA Ames Research Center			All comments are my own and
  (415) 604-6555				do not reflect NASA opinions
  Internet: dwsmith@ames.arc.nasa.gov		or policies.
  USPS: M/S 233-3
  Moffett Field, CA 94035-1000
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

wrp@PRC.Unisys.COM (William R. Pringle) (04/14/91)

In article <1991Apr11.144844.28800@riacs.edu> dwsmith@loki.arc.NASA.GOV (David Smith) writes:
>
>I have a question regarding I/O redirection.  I have a program in which
>writes to stdout and stderr.  I have redirected both of these to a file.
>
>Now comes the problem.  I need to capture stdout in a file along with
>stderr, but I also need stdout to go to the terminal for prompting of
>input.  Is this possible?  If so, how does one do this?

You can always write to the terminal with:

	echo "prompt message" > /dev/tty

In sh (or ksh), you can redirect stderr into stdout by:

	echo "message" 2>&1		# send stderr to stdout
	echo "message" 1>&2		# send stdout to stderr

You can have everything go to both the terminal and a file by:

	( whatever shell commands you want 2>&1) | tee file_name

Hope this helps!

Bill Pringle
prc.unisys.com

mike@bria.UUCP (Michael Stefanik) (04/15/91)

In an article, dwsmith@loki.arc.NASA.GOV (David Smith) writes:
|I have a question regarding I/O redirection.  I have a program in which
|writes to stdout and stderr.  I have redirected both of these to a file.
|
|Now comes the problem.  I need to capture stdout in a file along with
|stderr, but I also need stdout to go to the terminal for prompting of
|input.  Is this possible?  If so, how does one do this?

Try:

	$ [someprogram] 2>>somefile | tee /dev/tty >>somefile

-- 
Michael Stefanik, MGI Inc, Los Angeles | Opinions stated are never realistic
Title of the week: Systems Engineer    | UUCP: ...!uunet!bria!mike
-------------------------------------------------------------------------------
If MS-DOS didn't exist, who would UNIX programmers have to make fun of?

browning@nas.nasa.gov (David S. Browning) (04/16/91)

In article <1991Apr11.144844.28800@riacs.edu> dwsmith@loki.arc.NASA.GOV (David Smith) writes:

   I have a question regarding I/O redirection.  I have a program in which
   writes to stdout and stderr.  I have redirected both of these to a file.

   Now comes the problem.  I need to capture stdout in a file along with
   stderr, but I also need stdout to go to the terminal for prompting of
   input.  Is this possible?  If so, how does one do this?

I have a related question.  Is it possible, in csh, to redirect stdout
and stderr to different files?  Or to redirect stderr and not stdout?
I know how to do it in sh/ksh, but not in csh.

Thanks,
David

|============================================================================|
| Internet:  browning@nas.nasa.gov                  Phone:  (415) 604-4321   |
| UUCP:  {hplabs, mailrus, ucbvax, etc.}!ames!amelia!browning                |
|----------------------------------------------------------------------------|
|"the nice thing about true hopelessness is that you don't have to try again"|
| -- jules shear                                                             |
|============================================================================|

jimr@hp-lsd.COS.HP.COM (Jim Rogers) (04/17/91)

David W. Smith writes:

I have a question regarding I/O redirection.  I have a program in which
writes to stdout and stderr.  I have redirected both of these to a file.

Now comes the problem.  I need to capture stdout in a file along with
stderr, but I also need stdout to go to the terminal for prompting of
input.  Is this possible?  If so, how does one do this?

Answers may be mailed to me directly or you may post responses.  A solution
in for the csh, sh, ksh are all acceptable.

Thank you,


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  David W. Smith
  NASA Ames Research Center			All comments are my own and
  (415) 604-6555				do not reflect NASA opinions
  Internet: dwsmith@ames.arc.nasa.gov		or policies.
  USPS: M/S 233-3
  Moffett Field, CA 94035-1000
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
----------

The following modest example should show you how to do it.
Note that both stderr and stdout are sent to a file and to the screen 
together.  This should make the program fully interactive.



#!/bin/ksh

a_process()
{
# select writes to stderr
	select action in "First Action" "Second Action" "Terminate Actions"
	do
		if [ -z "$action" ]
		then
# write error message to stderr
			print 2 "Unknown action\nPress return to continue"
		else
#write responses to stdout
		case ${REPLY} in
		1 | 2)	print "${action}";;
		3)	print "Bye...";exit;;
		esac
		fi
	done
}
a_process 2>&1 | tee /dev/tty >> foobar




Jim Rogers
Hewlett-Packard Company
Colorado Springs, Colorado

prakash@fyrpwr.enet.dec.com (Mayank Prakash) (04/17/91)

In article <BROWNING.91Apr15152400@ew10.nas.nasa.gov>, browning@nas.nasa.gov (David S. Browning)
writes:
|->In article <1991Apr11.144844.28800@riacs.edu> dwsmith@loki.arc.NASA.GOV (David Smith) writes:
|->
|->   I have a question regarding I/O redirection.  I have a program in which
|->   writes to stdout and stderr.  I have redirected both of these to a file.
|->
|->   Now comes the problem.  I need to capture stdout in a file along with
|->   stderr, but I also need stdout to go to the terminal for prompting of
|->   input.  Is this possible?  If so, how does one do this?
|->
|->I have a related question.  Is it possible, in csh, to redirect stdout
|->and stderr to different files?  Or to redirect stderr and not stdout?
|->I know how to do it in sh/ksh, but not in csh.
|->
|->Thanks,
|->David
|->
--

In csh, try the following -

(cmd > outfile) >& errfile

to send stdout of cmd to outfile, and stderr to errfile. To redirect
stderr, and not stdout, is a bit harder. If stdout is the terminal, the
following would work -

(cmd | tee /dev/tty > /dev/null) >& errfile

It should give you ideas of how to do it in general.

-mayank.

+--------------------------------------------------------------------------+
| InterNet: Prakash@AIAG.ENET.DEC.COM                                      |
| UUCP:     ...!decwrl!aiag.enet.dec.com!Prakash                           |
| VoiceNet: (508)490.8139                                                  |
| BitNet:   prakash%aiag.enet at decwrl.dec.com                            |
| SnailNet: DEC, 290 Donald Lynch Blvd. DLB5-2/B4, Marlboro, MA 01752-0749 |
+--------------------------------------------------------------------------+

Disclaimer: The above is probably only line noise, and does not reflect the 
            opinions of anybody, including mine, far less my employer's.

tchrist@convex.COM (Tom Christiansen) (04/18/91)

From the keyboard of browning@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