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

Thu Feb 2 03:38:18 UTC 2012
Peter Blajev <pblajev at ucsd.edu>

On Wed, Feb 1, 2012 at 7:13 PM, Stephen Harris <lists at spuddy.org> wrote:

> 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
>  do
>   ...
>  done
>
> 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
>  b
>  c
>  d" | while read a
>  do
>    echo We have $a
>    read b
>    echo And $b
>  done
>  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.


Wow. Great lesson. Thank you Stephen.
It makes more sense now.

I'll save this email for sure.

--
Peter