I've done this a million times in the past, never had an issue with it. Now all of a sudden it doesn't work anymore. Originally had this issue on RHEL but I can actually reproduce it on FreeBSD too. We figured out a way around this but we fail to understand why it's happening in the first place. Hoping some shell script guru here might be able to shine a light on it.
We have a simple file with a list of hosts (in reality this is a CSV but the CSV is not the issue):
hosts.txt
Now, on a bourne shell I've done this countless times as a quick and dirty way of connecting to a bunch of hosts to get some info:
I expect this to loop over the hosts in the file and run ssh(1), log in on the other computer and run the command there. It works but only does the first host and the script ends. It never does the rest of the hosts in the file.
If I do this:
Or replace the ssh line with an echo for example:
It does loop over all the hosts in the file. Why doesn't this work (anymore) with ssh(1)?
This also works as expected:
If you put this in a script file you get the same issues, so it's not restricted to the command line, command line just makes it a little easier to test.
Why? Why does the
We have a simple file with a list of hosts (in reality this is a CSV but the CSV is not the issue):
hosts.txt
Code:
host1
host2
host3
Now, on a bourne shell I've done this countless times as a quick and dirty way of connecting to a bunch of hosts to get some info:
Code:
$ cat hosts.txt | while read h; do
> echo -n "$h: "
> ssh $h "uname -a"
> done
I expect this to loop over the hosts in the file and run ssh(1), log in on the other computer and run the command there. It works but only does the first host and the script ends. It never does the rest of the hosts in the file.
If I do this:
Code:
$ cat hosts.txt | while read h; do
> echo -n "$h: "
> ssh -n $h "uname -a"
> done
Code:
$ cat hosts.txt | while read h; do
> echo -n "$h: "
> echo ssh $h "uname -a"
> done
It does loop over all the hosts in the file. Why doesn't this work (anymore) with ssh(1)?
This also works as expected:
Code:
$ for h in $(cat hosts.txt); do
> echo -n "$h: "
> ssh $h "uname -a"
> done
If you put this in a script file you get the same issues, so it's not restricted to the command line, command line just makes it a little easier to test.
Why? Why does the
while ..;do
only executes the first host and apparently skips everything else. Why does ssh(1) all of a sudden require the -n
here? And why does a for .. ; do
work when a while ... ; do
doesn't?