better way to loop through a list of servers

I regularly do things where I loop through a list of servers to take some action. For example:

for s in `cat servers.txt` ; do
    echo; echo $s
    ssh $s 'do something'
done

I'm wondering (from a shell perspective) if there's an easier way of doing this than cat servers.txt

Yes I know about tools like mcollective, capistrano, etc - I'm often doing this to fix up mcollective problems :-)


Solution 1:

My quick and dirty... where servers.txt has a series of hosts or IPs, one-per-line.

#!/bin/bash

SERVER_LIST=/path/to/servers.txt

while read REMOTE_SERVER
do
        ssh $REMOTE_SERVER "do_something_cool"
done < $SERVER_LIST

Solution 2:

I use ClusterSSH.
It opens up a lot of small shells, and you can type to all of them in the same time. Really handy when you want to execute the same command on a lot of servers, but still see the output.
I use it like this: clusterssh $(~/get-servers.sh), but obviously you can do something like clusterssh $(cat servers.txt)
The result looks like this:

enter image description here

It's also available as a Debian package.

Solution 3:

To execute a simple task across a wide range of servers without using any tool designed for this purpose, regardless they require previous infrastructure or not, you can use a simple shell script called mussh, distributed as a package in many distributions.

You can call it with a list of hosts, a list of commands, store both things in files, and quite a few more options, like ssh-agent integration, proxy support, ... Check the manpage for all the details.

An example could be as simple as:

$ mussh -H host_list.txt -C command_list.txt