Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 28 Aug 1999 15:44:09 +0100
From:      Ben Smithurst <ben@scientia.demon.co.uk>
To:        Roger Hardiman <roger@cs.strath.ac.uk>
Cc:        hackers@freebsd.org
Subject:   Re: Help with exit status in shell script
Message-ID:  <19990828154409.B28779@lithium.scientia.demon.co.uk>
In-Reply-To: <37C79822.D28CD168@cs.strath.ac.uk>
References:  <37C79822.D28CD168@cs.strath.ac.uk>

next in thread | previous in thread | raw e-mail | index | archive | help
Roger Hardiman wrote:

> Build calls Stage1. Stage1 will return with an error code in some cases
> and we want to trap this and halt the Build script.
> 
>    ./stage1 2>&1 | tee stage1.out
>     if [ "X$?" != "X0" ] ; then 
> 
> Normally, $? will return the Exit Status of the last executed program.
> However, due to the pipe through Tee, the Exit Status I get is the
> exit status of Tee and not the exit status of the Stage1 script.
> 
> I still want to output the stage1 script to screen and a log file.
> How can I do this and preserve the exit status for the Build script.

There's a bit about this in the "Csh Programming Considered Harmful"
document, showing how "easy" it is in the  Bourne shel:

   Consider the pipeline:
   A | B | C
   You want to know the status of C, well, that's easy: it's in $?, or
   $status in csh. But if you want it from A, you're out of luck -- if
   you're in the csh, that is. In the Bourne shell, you can get it,
   although doing so is a bit tricky. Here's something I had to do where
   I ran dd's stderr into a grep -v pipe to get rid of the records in/out
   noise, but had to return the dd's exit status, not the grep's:
   device=/dev/rmt8
   dd_noise='^[0-9]+\+[0-9]+ records (in|out)$'
   exec 3>&1
   status=`((dd if=$device ibs=64k 2>&1 1>&3 3>&- 4>&-; echo $? >&4) |
   egrep -v "$dd_noise" 1>&2 3>&- 4>&-) 4>&1`
   exit $status;

See http://www-uxsup.csx.cam.ac.uk/csh.html for the rest.

so

exec 3>&1
exit_code=`((./stage1 2>&1 1>&3 3>&- 4>&-; echo $? >&4) |
	tee stage1.out 1>&2 3>&- 4>&-) 4>&1`
exec 3>&-

or something, should get it for you. I used `exit_code' rather than
`status' because `$status' is read-only in zsh, but that shouldn't be a
problem for plain old sh. You'd better add some comments explaining just
what it does :-)

-- 
Ben Smithurst            | PGP: 0x99392F7D
ben@scientia.demon.co.uk |   key available from keyservers and
                         |   ben+pgp@scientia.demon.co.uk


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19990828154409.B28779>