[comp.unix.questions] What's the return status of a pipeline???

harry@moncam.co.uk (Jangling Neck Nipper) (05/10/89)

I wrote a filter for lpr some time ago, but it's never worked
properly, and I was wondering if somebody might be able to
help me out.

The printcap entry is:

lp|ps|apple|lwriter|Apple Laserwriter:\
	:lp=/dev/null:if=/usr/local/bin/IF_lwriter:lf=/usr/adm/lprlog:\
	:sd=/usr/spool/lpd/apple:af=/usr/adm/lprlog:\
	:pw#102:pl#78:mx#0:

The filter program IF_lwriter is:

-------------------------------------

#!/bin/csh
#
# [-c] -w<width> -l<length> -i<indent> -n <user> -h <host> <accounting file>
#
# filter used by lpr -P[ps|apple] &c.

setenv LWRITER "LaserWriter Plus"
set BIN = /usr/local/bin

if ("$1" == "-c") then
	set user    = $6
	set host    = $8
	set acct    = $9
else
	set user    = $5
	set host    = $7
	set acct    = $8
endif

#
# Log this print...
#
echo ""                               >> $acct
date                                  >> $acct
echo $user@$host printing to $LWRITER >> $acct

#
# catch signals...
#
onintr quit

#
# DO IT!!!
#
$BIN/psfilter -b $* | $BIN/lwriter -pI "$LWRITER" $* >>& $acct

#
# Say what happened
#
quit:
set printer_status = $status
switch ($printer_status)

case 0:
	echo job was sucessful >> $acct
	breaksw

case 1:
	echo job failed and will be reprinted >> $acct
	breaksw

case 2:
	echo job deleted >> $acct
	breaksw

default:
	echo unknown status $printer_status >> $acct
	breaksw

endsw

exit $printer_status

-------------------------------------

It is the `lwriter' filter that *should* be determining the status,
namely 0, 1 or 2, and I've tried dummy shell scripts and found
that it's always the filter at the *end* of the pipe that determines
the status, so this should be okay, but in fact all I ever get is
status `0', no matter *what* return status I made `psfilter' or
`lwriter' return.  Is there anything fundamentally wrong with
the filter???
-- 
  ,---.'\ 
 (  /@ )/    Nothing is true.        
   /( _/  )  Everything is permitted.
   \,`---'

maart@cs.vu.nl (Maarten Litmaath) (05/11/89)

harry@moncam.co.uk (Jangling Neck Nipper) writes:
\...
\$BIN/psfilter -b $* | $BIN/lwriter -pI "$LWRITER" $* >>& $acct
\
\#
\# Say what happened
\#
\quit:

This `label command' resets $status to 0.

\set printer_status = $status
\...
-- 
 "`Goto considered harmful' considered |Maarten Litmaath @ VU Amsterdam:
      harmful" considered harmful!     |maart@cs.vu.nl, mcvax!botter!maart

chris@mimsy.UUCP (Chris Torek) (05/11/89)

(The exit status of a pipeline is supposed to be the exit status of the
last process in the pipeline.  4BSD sh does not always get this right.)

In article <186@marvin.moncam.co.uk> harry@moncam.co.uk
(Jangling Neck Nipper) writes:
[csh script; all but the important part deleted]
>onintr quit
>$BIN/psfilter -b $* | $BIN/lwriter -pI "$LWRITER" $* >>& $acct
>quit:
>set printer_status = $status

This will always set printer_status to 0.  Let us hear it for csh
`design':  the label `quit' succeeds, wiping out the exit status
from the pipeline above.

See:

	% (exit 1)
	% echo $status
	1
	% (exit 1)
	% foo:
	% echo $status
	0
	%

Moral: never try to use csh for shell scripts.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

jws@hpcljws.HP.COM (John Stafford) (05/12/89)

Don't use ksh either.  In some versions, the exit status of a pipeline
is the exit status of the last component to terminate, not that of the
last component of the pipe line (set +o monitor seems to restore the sh,
last component of the pipe line behavior, but that isn't documented).