4

this should probably be obvious to me, but I've been stuck for some time.

I'm trying to write a very simple bash loop to take a list of servers, retrieve some specific info from them, and save the output to a file based on that host address on the starting machine.

Code currently looks like:

#!/bin/bash

SERVER_LIST=/path/to/hosts

while read REMOTE_SERVER
do
    {
    ssh user@$REMOTE_SERVER 'show_stat_from_shell_command' 
} > "$REMOTE_SERVER"
done < $SERVER_LIST

The result from the above produces only a single output file for the first host in my list and then exits.

To head off some of the more obvious solutions, Ansible etc. are not an option due to this being a very restricted environment. For the same reason using a multi-shell or tmux is also not an option (I can only log into one system at a time from my host).

So, if someone could tell me exactly how I'm messing this up it would be appreciated!

3
  • If you remove the file redirection does it loop through the entire list as expected?
    – David King
    Commented Dec 23, 2015 at 18:22
  • Ok, so oddly no. Really should have checked that first. I'm basing my code on the idea of replacing a for loop using cat of the server list, since I couldn't make that work. The idea was the use while and a redirect to accomplish the same result.
    – Praxis
    Commented Dec 23, 2015 at 18:37
  • Welcome to Server Fault! I am voting to move this question to Unix & Linux because it is asking about how to use an application or write a script, not how to manage the system. This does not mean that the question is bad, but I believe it is a better fit for the other site.
    – Jenny D
    Commented Dec 23, 2015 at 18:58

2 Answers 2

6

Replace

ssh user@$REMOTE_SERVER 'show_stat_from_shell_command'

by

ssh user@$REMOTE_SERVER 'show_stat_from_shell_command' </dev/null

to prevent ssh reading from stdin ($SERVER_LIST) too. Or use ssh's option -n.


-n: Redirects stdin from /dev/null (actually, prevents reading from stdin).

1
  • Oh wow, I completely forgot that ssh will consume stdn entirely. What a miss. Massive thanks!
    – Praxis
    Commented Dec 23, 2015 at 18:59
3

There is another solution to this particular problem. It's called parallell ssh, pssh, and it does exactly what you want - it connects to machines based on a list, runs a command, and can save output in a log file or in a file based on the hostname.

The project lives at http://code.google.com/p/parallel-ssh/ .

2
  • Thanks for the suggestion, I'll be sure to check it out in the future!
    – Praxis
    Commented Dec 23, 2015 at 19:01
  • I've used it for exactly this purpose, and impressed some coworkers with the results :-)
    – Jenny D
    Commented Dec 23, 2015 at 19:22

You must log in to answer this question.