Run a ping command on list of servers and output to a file

9,076

Solution 1

OK, I believe I understand your question now.

On host1

Let us assume that you have host1 to which you connect with ssh via putty, on this host you shall install screen or tmux (from the package manager, they shall be there). I suggest screen since it is a little easier for a beginner.

Also, you need to be able to login to host2 from host1 therefore you need to setup a ssh key which will allow for login without a password. To perform this you need to run:

ssh-keygen -f ~/.ssh/host1tohost2

It will ask for a passphrase, to perform the script automatically (without the need for manual input of a passphrase) you shall set it to an empty passphrase. Keep host1 safe! Thanks to this key anyone in control of host1 also gains control of host2 (to the extent the user permissions allow).

That command will generate the following files:

~/.ssh/host1tohost2
~/.ssh/host1tohost2.pub

You shall copy ~/.ssh/host1tohost2.pub to host2:

scp ~/.ssh/host1tohost2.pub me@host2:~

On host2

Create ~/.ssh in host2 and move host1tohost2.pub there, then create a file called authorized_keys in that directory:

mkdir -f ~/.ssh
mv ~/host1tohost2.pub ~/.ssh
cd ~/.ssh
cat host1tohost2.pub >> authorized_keys

This allows for login from host1 to host2 without an interactive password prompt.

Next,

Let us assume that the file servers.txt is at /home/me/myservers/servers.txt on host2. This assumption is needed since we will be using this path in a script at host1.

Back to host1

The infinite loop script you need is:

#!/bin/sh

X_SECONDS=6
LOGFILE=~/mypings.log

while ((1)); do
    # >$LOGFILE  # clear log file (see comments)
    ssh -i ~/.ssh/host1tohost2 me@host2 'cat /home/me/myservers/servers.txt' |
    while read x; do
        echo "ping to $x"
        ping -c1 $x >> $LOGFILE
    done
    sleep $X_SECONDS
done

Let's assume that this script is saved to a file called pingservers.sh. But do not run it yet, since it will stop once you close putty. Now screen comes into the scene (you installed it, right?). Run:

screen

And apparently nothing changes. You're now in a shell that is being accessed through a socket in /var/run, this shell will not close once if you detach from it and then close putty (actually if you just close putty the OS will figure things out and not close the shell anyway, but let's do a proper detach for educational reasons). Before detaching it is time to run:

./pingservers.sh

It will run forever, and keep echoing a couple of messages while writing to the log file.

To detach from screen you need to enter Ctrl+A D (hold Ctrl, press A, release Ctrl and press D). And you're back in the original shell you logged in with putty, you can now close putty and have a coffee.

Once you login back into host1 the file ~/mypings.log shall be updated with more and more pings (no need to run screen again). To check the file being updated in real-time you can use:

tail -f ~/mypings.log

The arch linux wiki has much more useful info about ssh-keygen and ssh keys in general, and the same is true about gnu screen. These two articles are excellent source of information for both programs.

Solution 2

for i in `cat servers.txt` ; do ping -c1 $i 2>&1 | tee >> ping-output.txt; done

This executes a ping for each line in the file (using i as the variable that stores the value and referencing the variable with $i) and redirects all output into the [output] file. The 2>&1 part captures the stdout (ping results) and the stderr (no ping because no host error) into a file using the tee command.

Share:
9,076

Related videos on Youtube

Doug Coburn
Author by

Doug Coburn

Alireza Noori - (Website) Bachelor of Science in Computer Science Full Stack developer I’m professionally familiar with: Desktop: C# (Winforms, WPF, Metro, etc.), C++, Pascal, Java and VB Web: ASP.Net (Core + RazorPages, MVC, WebAPI, etc.), PHP, JavaScript, CSS, HTML, React DB: MSSQL, SQLite, MySQL, MongoDB, ... Visit my website at: https://alirezanoori.ir/

Updated on September 18, 2022

Comments

  • Doug Coburn
    Doug Coburn over 1 year

    I have a file servers.txt on a different server, with list of servers:

    server1.mydomain.com
    server2.mydomain.com
    server3.mydomain.com
    

    I want to first download this txt file, ping these servers and output the ping result into a file. And I want to do this on an infinite loop every x seconds.

    I have a VPS login and so far I have figured out to connect to the VPS using a program called putty.exe.

    How should I approach this? I would imagine I should write a script and set the server to run it each x seconds or use a while loop.

    • grochmal
      grochmal almost 8 years
      What do you mean by "on a different server"? If you're using putty then you're starting from an MS Windows machine to which you're logging into a Linux VPS (let's call it host1). Is the servers.txt file on host1 or on another host (let's call it host2)? The solution for both cases is not difficult but is very different.
    • Doug Coburn
      Doug Coburn almost 8 years
      @grochmal sorry for the confusion. It is on host2
  • Julie Pelletier
    Julie Pelletier almost 8 years
    To make the answer more complete, you should wrap it in another infinite loop as requested. Note that I see no benefit for using tee here as the ping command can be properly redirected on its own.
  • aeiounix
    aeiounix almost 8 years
    On my system, I created the example servers.txt file. When I ran the above command without the | tee part and it did not capture the message from the system about it being unresolvable which might be helpful. ping: unknown host server1.mydomain.com
  • Doug Coburn
    Doug Coburn almost 8 years
    Thanks for the answer. I get the loop and the syntax (I'm a programmer) but I'm having a little trouble understanding one thing. When I run this command, will I need to keep the putty open or will it run infinitely? (assuming I wrap this with another loop). I want it to run infinitely without my interaction.
  • aeiounix
    aeiounix almost 8 years
    while [ 1 ] ; do for i in cat servers.txt ; do ping -c1 $i 2>&1 | tee >> ping-output.txt; done ; done <-- will run indefinitely. But it will fill up the hard drive eventually. And doesn't show output. So, if you run screen, you can open up a new session and tail -f the output file. ¯(°_o)/¯ First real thought was install nagios with email notifications, but that's quite a leap. Check out fping: tecmint.com/install-fping-icmp-program-on-rhel-centos-6-5-4
  • aeiounix
    aeiounix almost 8 years
    watch nmap -sn server1.mydomain.com server2.mydomain.com server3.mydomain.com Will show results of the ping scan every 2 seconds.
  • Doug Coburn
    Doug Coburn almost 8 years
    OK. As far as I can understand this pretty much answers everything. But I want the file to just have 1 set of pings (not just appending to the existing file). One solution would be to delete the file before the while loop. Is there a better solution? Also, I assume that the servers.txt is not publicly accessible but it is in the host1 server using this method, correct?
  • grochmal
    grochmal almost 8 years
    I added a small edit (but left it commented it out in case other people find this question/answer through google), instead of deleting the file it is more elegant to overwrite it with an empty stream, i.e. >file (this is also faster than recreating the file). I'm a little confused about the second part of your comment, but i'll try to answer it: servers.txt is copied as a stream to the script at host1, it is copied each time so when it gets updated on host2 the script picks it. The communication happens over ssh therefore it is authenticated and encrypted.
  • Doug Coburn
    Doug Coburn almost 8 years
    Thank you very much. I'll try it and hopefully I can do everything without a problem.