[CentOS] Bash scripting - Remotely ran commands break while loop

Thu Feb 2 03:13:37 UTC 2012
Stephen Harris <lists at spuddy.org>

On Wed, Feb 01, 2012 at 07:03:33PM -0800, Peter Blajev wrote:
> On Wed, Feb 1, 2012 at 2:53 PM, Stephen Harris <lists at spuddy.org> wrote:
> > On Wed, Feb 01, 2012 at 01:07:31PM -0800, Peter Blajev wrote:
> > > echo " server2
> > > server2" | \
> > > while read confLine; do
> > >      echo "--> $confLine"
> > >      ssh peter@$confLine ls
> > >      echo "--> END $confLine"
> > > done

> > > Any idea what would cause the ssh command to break the while loop?
> >
> > "ssh" is reading from stdin and passing the data over to the remote
> > machine.  You can test this with
> >  ssh peter@$confLine 'read x ; echo we got $x'
> >
> > To stop it doing this, use the "-n" flag
> >  ssh -n peter@$confLine ls
> Unfortunately I can't always use the (-n) option. If I wan't to send data
> through the pipe then the (-n) won't work. For example (on top of my head):
>   mysqldump dB | ssh peter at remoteServer "mysql dB"

In this situation, ssh will read from the pipe and not from the "echo"
statement and so it won't break your while loop.

The thing you need to understand is how redirection works.
  echo foo | while read

Everything from the "while" to the "done" will have stdin configured to
read from the pipe (the output of "echo").   Here's an example:
  % echo "a
  d" | while read a
    echo We have $a 
    read b
    echo And $b
  We have a
  And b
  We have c
  And d

You can see that the "read" statement inside the loop is reading from
the pipe and so draining input.  

An "ssh" on its own, in this situation, would drain _all_ the input.
The "-n" flag tells ssh to not do this.  But, equally, when you do
  sqldump | ssh
then you've told ssh to take input from the output of sqldump, and so it's
no longer reading the from outer loop.

Instead of "ssh -n" you could do "ssh < /dev/null" or "echo | ssh" or
other options, and get the same sort of effect; you're setting up the
stdin to ssh to be from somewhere _other_ than your main echo.