$I'm running SCO 3.2.4.2 and ran across an odd problem. Take the following
$shell program named foo:
$
$TTY=`tty`
$echo "The value of TTY is: ${TTY}. Press RETURN \c"
$read anykey
$echo "Thanks."
$
$Now run:
$
$echo "Hello world." | foo
$
$You get (something like):
$tty: not a tty
$The value of TTY is: not a tty. Press RETURN
$
$and it "falls through" the read anykey part. What's also wierd is that I
$can have foo call foo.next and it (foo.next) behaves the same way.
$
$So the question is: How can I make a "read" behave at the tail end of a pipe?
The read is, in fact, behaving properly. You piped the text
Hello world.<LF> into it, and it in fact read that value into the
shell variable anykey. Were you to put
echo anykey says $anykey
in your foo script, it would print "anykey says Hello world."
Unfortunately, that shell variable is in a subshell, since the foo on
the end of the pipe is executed in a separate shell, and when that
shell terminates, the value of anykey goes away with it. You can't
update the value of anykey in a parent without some trickery. You
run into the same problem in a shell script in which you want to have
the output of something piped into a loop and still use the results
later on:
some_command | while read a b c
do
whatever
done
The while loop, along with the read and the whatever, get
executed in a subshell, at least in /bin/sh (I believe some
other shells can, in some circumstances, avoid subshells in some
cases in which /bin/sh uses them, but I don't know the details).
The error messages, presumably, come because the tty command
does an ioctl() on stdin, or something like that, and normally
stdin is a tty. In the case of a pipe, stdin is not a tty, and
therefore the tty command fails. To demonstrate this behaviour
of the tty command, try:
% tty
/dev/tty02
% tty < /dev/tty01
/dev/tty01
If you need to have a script in a subshell return an environment
variable, you'll have to make it put it somewhere at least somewhat
permanent, and that usually involves altering the script in a way
which may cause problems if you ever want to run it on its own.
You could put it in a file, for example, and have your parent read
that file (either as a second shell script to be read with . or
by READing it), or have it print a result on stdout and have the
parent use VARIABLE=`foo` to get at it.
--
----------------------------------------------------------------------------
Stephen M. Dunn, CNE, ACE, Sr. Systems Analyst, United System Solutions Inc.
104 Carnforth Road, Toronto, ON, Canada M4A 2K7 (416) 750-7946 x251