I need a script that will review a list of IPs for 200 servers and grab the Ubuntu OS information and deposit it to a file.

All my servers are Ubuntu versions between 14 and 18.

SSH is the notable method used to access each server using key-based authentication using RSA key generation.

Could I get some help with creating a script that accomplishes this?

The appended file can be placed at a generic nfs storage location (server01:/file-storage /mnt/lsb-info).

The script should do these tasks:

  1. Review list of IPs from IP_list.txt
  2. Log in to each server
  3. Execute command: lsb_release -a
  4. Append info to LSB_Release_Info.txt
  • @EliahKagan - I appreciate your consideration looking into this. All of the servers are Ubuntu ranging between versions 14 and 18, and yes, I use SSH to login to each server. I have about 200 servers I need to log into and grab this information. Its tedious, so I'm hoping I can script it to help end the suffering. :-) And actually, I only need the OS version not the entire 'lsb_release -a' info, so if you know how to reduce that down to IP-OSversion that would be ideal.
    – CrashFive
    Aug 22, 2019 at 19:24
  • 1
    Have you ever used any scripting language before?
    – user535733
    Aug 22, 2019 at 19:58
  • 1
    @CrashFive Add the information you provided in the above comment to the question, editing it. Aug 22, 2019 at 20:13
  • 2
    It could be as simple as installing pssh and then running parallel-ssh -h IP_list.txt -P lsb_release -r > LSB_Release_Info.txt Aug 22, 2019 at 23:03
  • 2
    Reviewers: This is not off-topic and, considering it can be done in one line, I don't see how it would be too broad. Also: unlike far too many questions on the site, the OP made substantial and effective efforts to add information on request, which led to an answer. (I've deleted my earlier comments requesting information, but you can check the edit history. Details on how the servers are accessed and how logins performed were promptly and helpfully given.) So for anyone who thinks this is a "gimme the code" or otherwise low-effort question: it is not. Aug 25, 2019 at 18:42

1 Answer 1


Since you're using key-based authentication with SSH, it is easy to automate running a command on many machines. You can write a simple script to do this, but you don't really need to. You can do it with a single command, something like:

xargs -a IP_list.txt -d'\n' -I{} ssh {} 'printf "\n%s:\n" {}; lsb_release -a' | tee -a LSB_Release_Info.txt

This runs one ssh command for each line of IP_list.txt, plugging the line in for {}. For this to work, each line should be an IP address or hostname of a server you want to SSH to. Suppose, for example, that IP_list.txt contains the line Then the SSH command that xargs runs for that line is:

ssh 'printf "\n%s:\n"; lsb_release -a'

What ssh does with that command is to attempt to connect to and to execute this code in a non-interactive shell:

printf "\n%s:\n"; lsb_release -a

That consists of two commands. The first prints a blank line followed by the line The second is lsb_release -a.

The ssh command can only succeed if you are logging in with the correct credentials:

  • As I've written it, your local username will be used. If that's not correct, you'll have to modify the command accordingly. For example, if all the machines have the same username as one another--e.g., foo--then you'd write ssh foo@{} in place of ssh {}.
  • As you probably know, you'll need to cache your decrypted private key with an authentication agent, to avoid needing to type your local SSH key passphrase in for each ssh command. My guess is that you have this set up already; if not, see man ssh-agent. (Likely it is sufficient to run eval "$(ssh-agent)" followed by ssh-add, and enter your passphrase.)

Piping the output of that xargs command with the | operator to tee -a LSB_Release_Info.txt shows you the output while also appending it to the (local) file LSB_Release_Info.txt. Error messages are not included in the file; those will only be shown to you. If you wanted to include them in the output file, you could use |& instead of |, but you're very unlikely to want them. More likely, you might only want to see error messages, in which case you can use >>LSB_Release_Info.txt instead of | tee -a LSB_Release_Info.txt--that is, just redirect to the file instead of piping to tee. Note that if you run tee without -a, or if you use > instead of >>, then you are overwriting LSB_Release_info.txt instead of appending to it.

I suggest testing this out first with an input file consisting of just a few IP addresses. Pressing Ctrl+C usually succeeds at stopping a long-running command, but I still suggest doing a bit of testing to get it right before running it for all your servers. For example, to write this answer I tested this on my local network with four IP addresses, and got output to my terminal (and in LSB_Release_Info.txt) like this:
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.3 LTS
Release:        18.04
Codename:       bionic
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 16.04.6 LTS
Release:        16.04
Codename:       xenial
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu Eoan Ermine (development branch)
Release:        19.10
Codename:       eoan
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.3 LTS
Release:        18.04
Codename:       bionic

That's what the output should look like with the command given above. You can adjust the command accordingly, then run it on all two hundred servers once it produces the output format you want.

  • thank you for this.
    – CrashFive
    Aug 23, 2019 at 20:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.