[comp.unix.questions] Redirecting stderr in csh

koreth@ssyx.ucsc.edu (Steven Grimm) (11/24/87)

How do you redirect stderr without redirecting stdout in csh?  In sh, you
can use "2> filename", but there doesn't seem to be a csh equivalent.

+New! Improved! Now 100% Artificial-+-+-----------------------------------+
|#   #  @@@  ****  &&&&& $$$$$ %   %| |Steven Grimm                       |
|#  #  @   @ *   * &       $   %   %+-+ ARPA: koreth@ucscb.ucsc.edu       |
|###   @   @ ****  &&&&    $   %%%%%| | UUCP: ...!ucbvax!ucscc!ssyx!koreth|
|#  #  @   @ * *   &       $   %   %+-+     ______________________________|
|#   #  @@@  *  ** &&&&&   $   %   %| |     |"Let's see what's out there."|
+-----with NutraSour(TM)!  No natural colors or preservatives!------------+

inna@daisy.UUCP (Inna Lauris) (11/26/87)

In article <1254@saturn.ucsc.edu> koreth@ssyx.ucsc.edu (Steven Grimm) writes:
>How do you redirect stderr without redirecting stdout in csh?  In sh, you
>can use "2> filename", but there doesn't seem to be a csh equivalent.

use "command >& filename" to redirect stderr

-- 
*****************************************************************
All I ask is the chance to prove that money cannot make me happy
             nsc!daisy!inna

dv@unicom.UUCP (David W. Vezie) (11/26/87)

In article <1254@saturn.ucsc.edu> koreth@ssyx.ucsc.edu (Steven Grimm) writes:
>How do you redirect stderr without redirecting stdout in csh?  In sh, you
>can use "2> filename", but there doesn't seem to be a csh equivalent.

You can use the "subshell" feature of csh, and do:
(cmd > /dev/tty) >& filename

That will send the standard output to /dev/tty (your terminal), and
the diagnostic output to filename.  Of course, if you want the standard
output to go somewhere else, that's easily done with:

(cmd > stdout_filename) >& stderr_filename

Pipes are also possible, for both the standard output and the diagnostic
output.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
(no real .signature yet)  		David W. Vezie
					{ucbvax|sun}!pixar!unicom!dv

chris@mimsy.UUCP (Chris Torek) (11/27/87)

>In article <1254@saturn.ucsc.edu> koreth@ssyx.ucsc.edu (Steven Grimm) writes:
>>How do you redirect stderr without redirecting stdout in csh?  In sh, you
>>can use "2> filename", but there doesn't seem to be a csh equivalent.

(To which the answer is `you cannot; there is none'.)

In article <209@unicom.UUCP> dv@unicom.UUCP (David W. Vezie) writes:
>You can use the "subshell" feature of csh, and do:
>(cmd > /dev/tty) >& filename

This *sometimes* does what is desired.  But there is no way to do
in csh the following (without using temp files, which might overflow):

	>Perrors; >ierrors; >perrors; >eerrors
	while loop; do
		P 2>>Perrors | i 2>>ierrors | p 2>>perrors | e 2>>eerrors
	done | filter
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

berke@acf8.UUCP (Wayne Berke) (11/27/87)

Try this:

	% (cmd_name > /dev/tty) >& stderr_file

Wayne Berke

berke@acf8.UUCP (Wayne Berke) (12/01/87)

Chris Torek writes:
>In article <209@unicom.UUCP> dv@unicom.UUCP (David W. Vezie) writes:
>>You can use the "subshell" feature of csh, and do:
>>(cmd > /dev/tty) >& filename
>
>This *sometimes* does what is desired.  But there is no way to do
>in csh the following (without using temp files, which might overflow):
>
>	>Perrors; >ierrors; >perrors; >eerrors
>	while loop; do
>		P 2>>Perrors | i 2>>ierrors | p 2>>perrors | e 2>>eerrors
>	done | filter

Never say never.  What about:

#!/bin/csh
touch Perrors; touch ierrors; touch perrors; touch eerrors
while (1)
    (P | (i | (p | (e > /dev/tty) >& eerrors) >& perrors) >& ierrors) >& Perrors
end

Yes, I know its ugly.  Also doesn't address how to pipe fit the output
of a while loop, but that's a different issue.

dv@unicom.UUCP (David W. Vezie) (12/01/87)

In article <9548@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:
>This *sometimes* does what is desired.  But there is no way to do
>in csh the following (without using temp files, which might overflow):
>
>	>Perrors; >ierrors; >perrors; >eerrors
>	while loop; do
>		P 2>>Perrors | i 2>>ierrors | p 2>>perrors | e 2>>eerrors
>	done | filter

You're talking about two different things here.  It is true that you
can't redirect the output of a loop.  However, the middle line there
is possible via:

( P | ( i | ( p | ( e > /dev/tty) >>&! eerrors) >>&! perrors) >>&! ierrors) \
								>>&! Perrors

Now, I will be the first to admit that this looks terrible
(do I hear some people screaming "HACK HACK HACK" :-),
but it IS possible.

Don't get me wrong here, I don't *like* csh, per se, it's just that
it's the only shell I have access to that supports job control and
history (I use the bourne shell for shell scripts, though, I mean I'm not
stupid!).
-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
David W. Vezie, Systems Hacker         |  "I support Star Wars (tm),
{{sun,ucbvax}!pixar,well}!unicom!dv    |           it's SDI I can't stand" --ME

berke@acf8.UUCP (Wayne Berke) (12/01/87)

Chris Torek writes:
>In article <209@unicom.UUCP> dv@unicom.UUCP (David W. Vezie) writes:
>>You can use the "subshell" feature of csh, and do:
>>(cmd > /dev/tty) >& filename
>
>This *sometimes* does what is desired.  But there is no way to do
>in csh the following (without using temp files, which might overflow):
>
>	>Perrors; >ierrors; >perrors; >eerrors
>	while loop; do
>		P 2>>Perrors | i 2>>ierrors | p 2>>perrors | e 2>>eerrors
>	done | filter

Never say never.  What about:

	#!/bin/csh
	touch Perrors; touch ierrors; touch perrors; touch eerrors
	while (loop)
		(P | (i | (p | (e > /dev/tty) >>& eerrors) \
		    >>& perrors) >>& ierrors) >>& Perrors
	end

Yes, I know its ugly.  Also, it doesn't address how to pipe fit the output
of a while loop, but that's a different issue.

chris@mimsy.UUCP (Chris Torek) (12/02/87)

In an article whose referent has been deleted by deficient software, I
included the following sh code, stating that the same thing cannot be
done in csh:
>>	>Perrors; >ierrors; >perrors; >eerrors
>>	while loop; do
>>		P 2>>Perrors | i 2>>ierrors | p 2>>perrors | e 2>>eerrors
>>	done | filter

In article <1650003@acf8.UUCP> berke@acf8.UUCP (Wayne Berke) writes:
>Never say never.  What about:
>
>#!/bin/csh
>touch Perrors; touch ierrors; touch perrors; touch eerrors

(First mistake! :-) `touch' and `>' are different; use `: > Perrors'
to clobber file Perrors, or use `cp /dev/null Perrors' [longer and
slower].  Your loop should then have `>>&'s, not `>&'s, below.)

>while (1)
>  (P | (i | (p | (e > /dev/tty) >& eerrors) >& perrors) >& ierrors) >& Perrors
>end
>Yes, I know its ugly.  Also doesn't address how to pipe fit the output
>of a while loop, but that's a different issue.

That was why I included the `| filter' in my example.  Also, the
`e > /dev/tty' is still wrong even without the `| filter' in the
sh example.  Consider:  Assuming the C shell script is in the file
`example.csh', running `example.csh' works as expected, but running
`example.csh > ex.out' works rather differently---or more accurately,
works in precisely the same way!  `ex.out' winds up empty, instead
of having the output from `e'.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

dv@unicom.UUCP (12/04/87)

I didn't write the article Chris replied to, but I said the same thing,
so I'll reply to this:

In article <9586@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:
>>while (1)
>>  (P | (i | (p | (e > /dev/tty) >& eerrors) >& perrors) >& ierrors) >& Perrors
>>end
>
>That was why I included the `| filter' in my example.  Also, the
>`e > /dev/tty' is still wrong even without the `| filter' in the
>sh example.  Consider:  Assuming the C shell script is in the file
>`example.csh', running `example.csh' works as expected, but running
>`example.csh > ex.out' works rather differently---or more accurately,
>works in precisely the same way!  `ex.out' winds up empty, instead
>of having the output from `e'.

That's true.  There's no way to have the well-buried 'e' know where
the origional stdout was.  I suppose you could do something with
named pipes (if you had them), but at that point, it would be easier
to re-write the script in Bourne Shell.

I don't really see any reason why to write shell scripts in csh
(unless you have a pressing need to have multiple-element variables).
But the (cmd > file) >& otherfile is handy.  For example, I have an
alias like:

alias MK '(make \!* >! MKCOMS) >&! MKERRS &'

So that the commands go in one file, and the diags go in another
file.
-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
David W. Vezie, Systems Hacker         |  "I support Star Wars (tm),
{{sun,ucbvax}!pixar,well}!unicom!dv    |           it's SDI I can't stand" --ME