rsh terminates while loop

101 views
Skip to first unread message

william E Davidsen

unread,
Dec 14, 1992, 3:21:47 PM12/14/92
to

A friend just brought this one in, and I've simplified it down to
something you can type in and ponder. He wants to call a shell script
with a filename, and read two variables per line from the file, and
execute a command on a remote machine using rsh, including the two
values read off a line.

It appears that the rsh does /something/ which wipes out the stdin of
the while loop. What I would like to understand is what's happening (I
already have an ugly but functional workaround).

$ cat y.tmp
qx1 -a
qx2 -a
danqx -l
$ cat x.tmp
#!/bin/sh
while read host flags
do
result=`rsh $host uname $flags`
echo "$host: $result"
done
$ ./x.tmp < y.tmp
qx1: qx1
$

Note that after reading a single line from the file the while loop ends.
Any command other than rsh does not cause this, and if you use ksh you
get an illegal IOCTL fault (under SunOS).

This fails under SunOS and HP-UX, but works with SCO ODT at a minimum,
supposedly fails on virtually anything with a form of rsh (aka rcmd,
remsh, etc) based on BSD code. I *think* it's a bug in rsh in the
redirecting of the i/o to sockets and pulling it back, but I don't
swear to it.

If anyone has some words of wisdom on this I'd love to hear them, it
really should be valid as posted. I'll try to get a chance to test on a
few other machines in the next few days.

--
bill davidsen, GE Corp. R&D Center; Box 8; Schenectady NY 12345
Keyboard controller has been disabled, press F1 to continue.

DaviD W. Sanderson

unread,
Dec 15, 1992, 12:46:05 AM12/15/92
to
In article <1992Dec14....@crd.ge.com> davi...@crd.ge.com (bill davidsen) writes:
>It appears that the rsh does /something/ which wipes out the stdin of
>the while loop.

Yes. rsh eats its standard input and gives it to the remote command.
The rsh man page on my system says this:

The rsh command sends standard input from the local command
line to the remote command

>If anyone has some words of wisdom on this I'd love to hear them,

Redirect the rsh input from /dev/null:

#!/bin/sh
while read host flags

do result=`rsh $host uname $flags < /dev/null`
echo "$host: $result"
done

DaviD W. Sanderson (d...@ssec.wisc.edu)

Philip A Guenther

unread,
Dec 14, 1992, 7:01:10 PM12/14/92
to
In article <1992Dec15....@cs.wisc.edu> d...@ssec.wisc.edu (DaviD W. Sanderson) writes:
Redirect the rsh input from /dev/null:
Or just use rsh -n.

Philip
--
guen...@stolaf.edu (Philip Guenther) | The ACC might agree with me,
Student Sys Prog, Academic Computing Center | but with that bunch, (and me)
St Olaf College, Northfield, MN 55057-1001 | you never know... :-) :-| :-(
"Life makes sense? LIFE MAKES SENSE!!? Where do people get these ideas?"-me

Scott Merrilees

unread,
Dec 15, 1992, 8:57:18 PM12/15/92
to
davi...@ariel.crd.GE.COM (william E Davidsen) writes:


> It appears that the rsh does /something/ which wipes out the stdin of
>the while loop. What I would like to understand is what's happening (I
>already have an ugly but functional workaround).

>$ cat y.tmp
>qx1 -a
>qx2 -a
>danqx -l
>$ cat x.tmp
>#!/bin/sh
>while read host flags
>do
> result=`rsh $host uname $flags`
> echo "$host: $result"
>done
>$ ./x.tmp < y.tmp
>qx1: qx1
>$

>Note that after reading a single line from the file the while loop ends.
>Any command other than rsh does not cause this, and if you use ksh you
>get an illegal IOCTL fault (under SunOS).

use 'rsh -n' if it works for you, otherwise use 'rsh </dev/null'.

What happens is that the local rsh can't know when the remote process need
input, so it gobbles up stdin and passes it to the remote process, thus
using all your input. If the remote process doesn't use all or any of the
input, then it is lost, because it isn't passed back and reinserted into
stdin.

Sm
--
Scott Merrilees, BHP Information Technology, Newcastle, Australia
Internet: S...@bhpese.oz.au Phone: +61 49 40 2132 Fax: ... 2165

william E Davidsen

unread,
Dec 16, 1992, 11:33:49 AM12/16/92
to
In article <1992Dec15....@cs.wisc.edu>, d...@ssec.wisc.edu (DaviD W. Sanderson) writes:

| Redirect the rsh input from /dev/null:
|
| #!/bin/sh
| while read host flags
| do result=`rsh $host uname $flags < /dev/null`
| echo "$host: $result"
| done

I told several people who mailed me suggestions to redirect the input
that I had tried it before posting. However, it seems that what I tried
was:


result=`rsh $host uname $flags` < /dev/null

rather than


result=`rsh $host uname $flags < /dev/null`

which works.

This is somewhat non-intuitive, and seems to contradict what the man
pages say, although I couldn't find anywhere in which the context of the
`expression` was clearly stated as being (or not being) effected by
redirection.

Thanks to the people who mailed solutions to me, it's clear that
redirection within the quotes will protably work, even if it's not as
clear that redirection outside the quotes doesn't.

DaviD W. Sanderson

unread,
Dec 16, 1992, 2:06:54 PM12/16/92
to
In article <1992Dec16.1...@crd.ge.com> davi...@crd.ge.com (bill davidsen) writes:
>However, it seems that what I tried was:
> result=`rsh $host uname $flags` < /dev/null
>rather than
> result=`rsh $host uname $flags < /dev/null`
>which works.
>
>This is somewhat non-intuitive,
...

>it's clear that redirection within the quotes will protably work,
>even if it's not as clear that redirection outside the quotes doesn't.

Let me explain.

The shell (sh/ksh anyway) expands command substitutions in a 'simple
command' (to use the man page terminology) prior to executing the
resulting 'simple command' or processing its i/o redirections. This
makes sense, because if i/o redirections for a 'simple command' ALSO
applied to its command substitutions then

ls -l `echo *.c` > foo

would redirect the result of the 'echo *.c' into the file 'foo' instead
of making the result of the echo part of the 'ls' command line. The
shell would then run the 'ls -l' command with no additional arguments,
also with its output redirected to the file 'foo'. Fortunately, this
is NOT what the shell actually does.

So, to return to the rsh example, in the command

result=`rsh $host uname $flags` < /dev/null

the redirection applies to the 'simple command' (which in this
particular case happens to be an assignment), not the rsh. When the
shell executes the rsh it has not yet processed the redirection. Since
assignments neither read nor write any file descriptors, the i/o
redirection for the assignment happens to have no effect on the
assignment itself. On the other hand, in the command

result=`rsh $host uname $flags < /dev/null`

the redirection is part of the command the shell executes when it
expands the command substitution in the assignment 'simple command', so
the redirection DOES apply to the rsh in this case.

DaviD W. Sanderson (d...@ssec.wisc.edu)

Reply all
Reply to author
Forward
0 new messages