#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2012
    Posts
    12
    Rep Power
    0

    SSH to many servers from script


    Hi All,

    I am new to *ix environment and also new to the forum.
    I need to find the version of an application which is running on more than 50 servers. Manually I can do it by logging onto each server and check.

    But is there anyway/script which could take the servers list from a file >> run the command >> store the output in the specified file.

    something like

    ssh [servername from the file] 'command' [output]

    Thanks in advance!!!
  2. #2
  3. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,595
    Rep Power
    4207
    There are a couple of ways to do this:

    One way to do this is to first setup a trusted key exchange (Google for "ssh key exchange" for details on how to set it up), so that you can ssh from your box into all 50 boxes without being prompted for a password.

    Once you've got the key exchange setup, then it is simply a matter of writing a quick shell script to run your command on multiple servers

    ssh server1 'command and arguments' >> /path/to/local_output_file
    ssh server2 'command and arguments' >> /path/to/local_output_file
    ssh server3 'command and arguments' >> /path/to/local_output_file
    ...
    ...
    ssh server50 'command and arguments' >> /path/to/local_output_file
    The output of all the commands will be written to /path/to/local_output_file so you can examine it later. You might want to put an "rm /path/to/local_output_file" at the top of the shell script, if you want a fresh file every time you run your shell script.

    A second way to do this is to use the Expect command. You can either script it out in a shell script, or there are various packages that allow you to use Expect from languages like perl and python (I've written scripts in both languages that use Expect). This scheme doesn't need you to set up a ssh key-exchange if you desire -- you can then tell the script to ssh into a server, expect the password prompt and then send the password over. You can then tell expect to run your command and capture its output with your script and print it to screen or log to file or whatever.

    Comments on this post

    • harshajd agrees
    Up the Irons
    What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home.
    "Death Before Dishonour, my Friends!!" - Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest
    Down with Sharon Osbourne

    "I wouldn't hire a butcher to fix my car. I also wouldn't hire a marketing firm to build my website." - Nilpo
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2012
    Posts
    12
    Rep Power
    0

    Smile


    Thanks!!!

    The solution
    ssh server1 'command and arguments' >> /path/to/local_output_file
    ssh server2 'command and arguments' >> /path/to/local_output_file
    ssh server3 'command and arguments' >> /path/to/local_output_file


    could work fine if we have some 50-80 servers. How about the environment which consists more than say a 1000 servers. Is there any way that server names can be read from a file and redirect the output to the single file?
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Regular (2000 - 2499 posts)

    Join Date
    Mar 2006
    Posts
    2,400
    Rep Power
    1688
    Indeed there is ... you have the basis of the command already, convert the hostname to a variable and obtain that variable's value from a file in a loop, such as:

    Code:
    for server in $(cat my_servers.txt)
    do
      ssh $server 'command and arguments' >> /path/to/local_output_file
    done
    The moon on the one hand, the dawn on the other:
    The moon is my sister, the dawn is my brother.
    The moon on my left and the dawn on my right.
    My brother, good morning: my sister, good night.
    -- Hilaire Belloc
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2012
    Posts
    12
    Rep Power
    0
    I tried this (considering that I have established a trusted key exchange so no auth needed)

    #!/bin/sh
    # server list
    SERVERS="server1 Server2 Server3 .. Server50"

    #output holder file
    outputFile = "/home/harshajd/test.txt"

    for host in $Servers
    do
    ssh $host 'arguments and commands' >> $outputFile
    done


    I was unable to get the output in the txt file.
  10. #6
  11. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,595
    Rep Power
    4207
    SimonJM's instructions work correctly if you want to read the server names from a file.

    In your case, you've defined a variable with a list of servers, but your problem is that you've forgotten that variable names are caSe-SeNsitiVe. That's the main problem in your code. You define the variable as SERVERS, but later refer to it as $Servers (Note the case.) If you'd referred to it as $SERVERS instead, then things would have worked better.
    Up the Irons
    What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home.
    "Death Before Dishonour, my Friends!!" - Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest
    Down with Sharon Osbourne

    "I wouldn't hire a butcher to fix my car. I also wouldn't hire a marketing firm to build my website." - Nilpo
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Regular (2000 - 2499 posts)

    Join Date
    Mar 2006
    Posts
    2,400
    Rep Power
    1688
    Change the $(cat ....) to $(echo "$Servers") , or whatever you end up calling the variable.
    The moon on the one hand, the dawn on the other:
    The moon is my sister, the dawn is my brother.
    The moon on my left and the dawn on my right.
    My brother, good morning: my sister, good night.
    -- Hilaire Belloc

IMN logo majestic logo threadwatch logo seochat tools logo