1

Could anyone of you explain why the following bash while loop ends execution after the first iteration when ssh is executed in it's body, please?

Input file:

$ cat hosts
192.168.223.21     miner01
192.168.223.23     miner03
  • While without ssh - two iterations:
$ while IFS=' ' read -r IP HOST; do echo "ip=$IP hostname=$HOST"; done < hosts
ip=192.168.223.21 hostname=miner01
ip=192.168.223.23 hostname=miner03
$
  • While with ssh in body - one iteration:
$ while IFS=' ' read -r IP HOST; do echo "ip=$IP hostname=$HOST"; ssh $HOST hostname ; done < hosts
ip=192.168.223.21 hostname=miner01
miner01
$

I also executed it with set -x but I can't see the reason for such behavior:

$ while IFS=" " read -r IP HOST; do echo "ip=$IP hostname=$HOST"; ssh $HOST hostname; done < hosts
while IFS=" " read -r IP HOST; do echo "ip=$IP hostname=$HOST"; ssh $HOST hostname; done < hosts
+ IFS=' '
+ read -r IP HOST
+ echo 'ip=192.168.223.21 hostname=miner01'
ip=192.168.223.21 hostname=miner01
+ ssh miner01 hostname
miner01
+ IFS=' '
+ read -r IP HOST
$

Bash version:

$ bash --version
bash --version
GNU bash, version 5.0.3(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
gbajson
  • 1,531
  • 13
  • 32

1 Answers1

4

ssh also consumes standard input. Try to replace ssh $HOST hostname with cat or nl, to understand conceptually why it does not work. After the command consumes the input, while ends since there is nothing else to read.

Since you do not need ssh to consume stdin, redirect it. This works:

while IFS=" " read -r IP HOST; do
  echo "ip=$IP hostname=$HOST"
  ssh $HOST hostname < /dev/null
done < hosts
Amadan
  • 191,408
  • 23
  • 240
  • 301
  • Thanks for this explanation! I added '-n' (it redirects stdin from /dev/null), which also solved this problem. – gbajson Oct 18 '19 at 10:56
  • 1
    Oh, yeah, that also works. `< /dev/null` is just more general, in case someone has the same problem with something that is not `ssh`. – Amadan Oct 18 '19 at 11:05
  • Works like a charm. Thanks a lot @Amadan – Kiran Jul 01 '23 at 19:01