[comp.unix.questions] Subprocess lives on..........

jc@heart-of-gold (John M Chambers) (11/15/88)

Here's a good Bourne-shell puzzle to make your day.  I know it has 
wasted a good chunk of mine already, so I thought I'd share the fun.

This is running on a Sun 3/260, release 3.4 of SunOS.  I have a little
Bourne-shell script:

| #!/bin/sh
| #   GrafRoute host
| # This generates a graph of the "netstat -r" Use data for host, 
| # which may be the destination or the gateway.
| # 
| while true
| do  netstat -r |grep $1 |cut -c49-59
|     sleep 6
| done | graf -PD +H +V -a -T'Route "'$1'" packet rate'
|

What it's trying to do is run "netstat -r" every 6 seconds, cut out the
use (i.e., packet rate) for a specified host, and feed it to "graf", a
cute little program that eats data on its standard input and displays
a graph on the screen.

When started up, this script works just fine; it gives me exactly the
graph I want, and runs for hours with no problems.  However, when I use
the SunView menu item "Quit", a curious thing happens.  The graf process
exits normally, the window closes down, and the shell exits.  If running
in the foreground, I get a shell prompt; if running in the background, I
get a job-termination message.  All looks normal.  But 6 seconds later,
and every 6 second thereafter, a newline is sent to standard output by
someone.  Who?  Well, it seems that the while loop in the script is still
in there running....

This sorta surprises me, because I'd think the exiting of the outer shell
would kill off the inner one that does the loop.  But who am I to question
the wisdom of the design?  

Can anyone figure out how to make the while-loop exit when graf terminates
and the script exits?  I've tried playing arount with $? and traps, but I 
clearly don't know what I'm doing.  I even tried a "kill -HUP 0", and it
worked.  But all my windows also exited and I got a login prompt.  Sorta
overkill, if you ask me.

(If you solve the problem, maybe I'll send you a copy of graf.c, so you can
also graph arbitrary streams of numbers.)
-- 
From:	John Chambers <mitre-bedford.arpa!heart-of-gold!jc>
From	...!linus!!heart-of-gold!jc (John Chambers)
Phone	617/217-7780
[Send flames; they keep it cool in this lab :-]

logan@vsedev.VSE.COM (James Logan III) (11/16/88)

In article <167@heart-of-gold> jc@heart-of-gold (John M Chambers) writes:
>Can anyone figure out how to make the while-loop exit when graf terminates
>and the script exits?  I've tried playing arount with $? and traps, but I 
>clearly don't know what I'm doing.  I even tried a "kill -HUP 0", and it
>worked.  But all my windows also exited and I got a login prompt.  Sorta
>overkill, if you ask me.

The shell really should exit without leaving the while loop
running (at least under Sys V) because the while loop will be
writing on a pipe with no one to read it.  This SHOULD cause a
SIGPIPE signal to kill the subshell that's running the while
loop.  Even if the subshell was ignoring the SIGPIPE signal, I
can't see how it would start writing to your terminal!  My first
guess at a fix is this:  

#!/bin/sh
#   GrafRoute host
# This generates a graph of the "netstat -r" Use data for host, 
# which may be the destination or the gateway.
# 
(
	trap "exit 0" 1 13 15;
	while true; do
		netstat -r |
		grep $1 |
		cut -c49-59;
		sleep 6;
	done;
) |
graf -PD +H +V -a -T'Route "'$1'" packet rate';

I don't know what SunView does to terminate the process.  Maybe
it sends a SIGHUP or a SIGTERM?  Anyway, this script will exit
when it receives either signal. (Theoretically!) 

			-Jim
-- 
Jim Logan		logan@vsedev.vse.com
(703) 892-0002		uucp:	..!uunet!vsedev!logan
			inet:	logan%vsedev.vse.com@uunet.uu.net