Jan 302012
 
Shell Scripting

Few times in administrative jobs we need to make sure some services or ports are always open and listening to monitor the same we can use below script can be used to ping and telnet to different hosts running on different ports. This bash script to ping multiple hosts can be used also to  telnet multiple hosts.

Things required:

Host_PortFile.txt – This file contains all the host names and port numbers needs to be pinged and telnet. Put your host names and ports like below and save it.

techpaste.com:80
yahoo.com:80
google.com:443
gmail.com:443
noerror.com:81

 

Below is the bash script:

#!/bin/bash
#bash to check ping and telnet status.
#set -x;
#
#clear
SetParam() {
export URLFILE="Host_PortFile.txt"
export TIME=`date +%d-%m-%Y_%H.%M.%S`
export port=80
export STATUS_UP=`echo -e "\E[32m[ RUNNING ]\E[0m"`
export STATUS_DOWN=`echo -e "\E[31m[ DOWN ]\E[0m"`
export MAIL_TO="admin(at)techpaste(dot)com"
export SHELL_LOG="`basename $0`.log"
}

Ping_Hosts() {

SetParam
cat $URLFILE | while read next
do

server=`echo $next | cut -d : -f1`

ping -i 2 -c 6 $server > /dev/null 2>&1

if [ $? -eq 0 ] ; then
echo "$TIME : Status Of Host $server = $STATUS_UP";
else
echo "$TIME : Status Of Host $server = $STATUS_DOWN";
echo "$TIME : Status Of Host $server = $STATUS_DOWN" | mailx -s "$server Host DOWN!!!" $MAIL_TO

fi
done;
}

Telnet_Status() {

SetParam

cat $URLFILE | while read next
do

server=`echo $next | cut -d : -f1`
port=`echo $next | awk -F":" '{print $2}'`

TELNETCOUNT=`sleep 5 | telnet $server $port | grep -v "Connection refused" | grep "Connected to" | grep -v grep | wc -l`

if [ $TELNETCOUNT -eq 1 ] ; then

echo -e "$TIME : Port $port of URL http://$server:$port/ is \E[32m[ OPEN ]\E[0m";
else
echo -e "$TIME : Port $port of URL http://$server:$port/ is \E[31m[ NOT OPEN ]\E[0m";
echo -e "$TIME : Port $port of URL http://$server:$port/ is NOT OPEN" | mailx -s "Port $port of URL $server:$port/ is DOWN!!!" $MAIL_TO;

fi
done;
}
Main() {
Ping_Hosts
Telnet_Status
}
SetParam
Main | tee -a $SHELL_LOG

Above script will create a log with the script name like if the shell script is stored as shell.sh then the log name for this script will be shell.log, once you run the script. A sample output is given below

ping and telnet script sample output

 

 

Thanks to Fr3dY for a new script which can also be used for the same tasks like ping, telnet and curl. Please check out this comment for the script

  23 Responses to “Bash Script To Ping And Telnet multiple hosts”

  1. not work! get error " Can't exec /bin/bash at C:Perlbinpingtel.pl line 1."

  2. not work ,i get “Can’t exec /bin/bash at C:\Perl\bin\pingtel.pl line 1.”

    • Hi Issa,

      Check you have access to /bin/bash as this is a bash script and runs on UNIX systems.

      save it as pingtel.sh and RUN it from a UNIX machine.

  3. THANK YOU!!
    Big time save and a good base point to start a bigger script.

  4. How would you automate this script if there are multiple source hosts and multiple destination hosts. Logging into each source host to check if its destination hosts had necessary port is open would be time consuming. How to automate this situation.

  5. Excellent work, thanks

  6. Thankyou

  7. i just follow your script to be able put in my testing server anyway im able to ran manually the scrip but when i put in the crontab looks script its not working the log SHELL_LOG was not updated it

    • What was the error you are seeing while running the script. Can you try to give a absolute file name for SHELL_LOG

      Example:
      export SHELL_LOG=”mylog.log”

      And Make sure you have “tee” in your PATH, commandline i.e. at /usr/bin/tee.

  8. Can you please explain this line ??

    TELNETCOUNT=`sleep 5 | telnet $server $port | grep -v “Connection refused” | grep “Connected to” | grep -v grep | wc -l`

    and what does grep -v grep mean ??

    • Hi Vicky,

      each five seconds it will check the count of Connected telnet sessions. grep -v grep is to remove the grep commands process from the list of outputs. You can check MAN pages of grep to find out more on -v option.

      Thanks

  9. I tried your script with host list having “Connection refused” in between of the input file.
    In your example you used “noerror.com:81″ at the end of file.

    The script comes out of the loop on encountering no connections and does not execute the remaining list of server:port

    Please let me know if i am missing anything here.

    • I just tried again with jumbling up the failed and working hosts its fine it does not skip.
      You are not seeing the status of the host as instead of printing the status down in console it sends a mail to admin stating the status is down for the host. you can just add one more line before below entry to let it print on console too. For convenience I have updated the same in the above article too just copy the script once again and check.

      echo “$TIME : Status Of Host $server = $STATUS_DOWN”;
      echo “$TIME : Status Of Host $server = $STATUS_DOWN” | mailx -s “$server Host DOWN!!!” $MAIL_TO

  10. Hi! I’ve created a script to check connectivity using TELNET, NC or CURL as commands, and accepting different-formatted destinatio server list.
    Here it is, hope you like it!

    connect.sh
    ————————————

    #!/bin/bash

    #SCRIPT FOR TESTING CONNECTIVITY WITH A LIST OF URLs by Fr3dY
    #
    #1.5: Added support for NC
    #
    #1.4: Added error messages when using TELNET
    # Added error codes to be ignored when using CURL
    #
    #1.3: When using CURL, it shows a OK or ERROR message
    # The URL parser also admits the host:port format (and even host without port, using a default one)
    # Included the script version in the app messages
    # Misc. fixes
    #
    #1.2: Modified TELNET usage, no CTRL-C capture anymore (it connects automatically now)
    # Misc. fixes
    #
    #1.1: Added a URL text file as input parameter
    # Added CURL as alternate method
    # Added a parser to use complete connection strings (they’re converted automatically when using TELNET)
    # Misc. fixes
    #
    #1.0: Initial version
    #

    #Version
    version=1.5

    #Number of parameters
    numberParameters=$#

    #Command for testing URLs (right now it accepts ‘telnet’ and ‘curl’)
    command=$1

    #URL file to load
    file=$2

    #List of errors to be ignored when using CURL
    ignoredErrors=(52 403 404 500)

    #Iterator (obsolete)
    i=0

    #PID of the child process to be killed when using CTRL-C (obsolete)
    pid=999999999999

    #Connection timeout
    timeout=3

    #Default Port if not specified in the host:port format
    defaultPort=80

    #CURL parameters
    curlParameters=(–connect-timeout $timeout –insecure -S -s -f -o /dev/null)

    #List of host and ports to check (now they’re loaded as a file)
    #HOSTS_LIST is defined in f_checkCall, after verifying the syntax

    #List size
    #LIST_SIZE is defined in f_checkCall, after verifying the syntax

    #Temporal file
    randomNumber=$RANDOM
    tempfile=$randomNumber.temp

    #Variable init
    host=0
    port=0
    hostport=0
    proto=http

    #Function that process the list of hosts and execute the connectivity check (telnet, curl, …)
    #PID of each background process is kept, to kill it if remains active
    f_processList () {
    if [ ${i} -lt ${LIST_SIZE} ]
    then
    #Format list if TELNET is used (sintax is ‘telnet host port’ and not ‘telnet host:port’)
    #Any other conversion functions could be added if necessary
    if [ $command = “telnet” ]
    then
    f_convertFormat
    f_executeTelnet
    f_killTimeout
    elif [ $command = “nc” ]
    then
    f_convertFormat
    f_executeNC
    else
    f_executeCurl
    fi
    i=$(($i + 1))
    f_processList
    fi
    }

    #Function to convert the URL format to HOST PORT (for using TELNET, NC…)
    #Admits ‘host:port’ and ‘protocol://host:port/path’ –> they’re converted to ‘host port’)
    f_convertFormat () {

    COMPLETE_URL=${HOSTS_LIST[$i]}

    if [[ $COMPLETE_URL == */* ]]
    then
    format=url;
    else
    format=hostport;
    fi

    if [ $format = “url” ]
    then
    #Obtain the protocol
    proto=”`echo $COMPLETE_URL | grep ‘://’ | sed -e’s,^\(.*://\).*,\1,g’`”
    #Get the URL after removing the protocol
    url=`echo $COMPLETE_URL | sed -e s,$proto,,g`
    #Extract user and password (if any)
    userpass=”`echo $url | grep @ | cut -d@ -f1`”
    pass=`echo $userpass | grep : | cut -d: -f2`
    if [ -n “$pass” ]; then
    user=`echo $userpass | grep : | cut -d: -f1`
    else
    user=$userpass
    fi
    #Get the host. If no port is defined, the default one is used (attending to the protocol)
    hostport=`echo $url | sed -e s,$userpass@,,g | cut -d/ -f1`
    port=`echo $hostport | grep : | cut -d: -f2`
    if [ -n “$port” ]; then
    host=`echo $hostport | grep : | cut -d: -f1`
    else
    if [ $proto = “http://” ]
    then
    port=80
    elif [ $proto = “https://” ]
    then
    port=443
    elif [ $proto = “ftp://” ]
    then
    port=21
    elif [ $proto = “ftps://” ]
    then
    port=22
    fi
    host=$hostport
    hostport=$host:$port
    fi
    else
    host=`echo $COMPLETE_URL|cut -d “:” -f1`
    port=`echo $COMPLETE_URL|cut -d “:” -f2`
    #If no port is defined, the default one is used
    if [ $host = $port ]
    then
    port=$defaultPort
    fi
    fi
    #The $host and $port variables are set for their incoming usage by using TELNET or NC
    }

    #Function that executes TELNET on the selected host
    f_executeTelnet () {
    CURRENTHOST=”$host $port”
    echo “Checking connection with $host:$port”
    $command $host $port > $tempfile 2>/dev/null &
    #Keep the child process PID, to stop it later if it remains active
    pid=$!
    sleep $timeout
    output=`tail -1 $tempfile`
    if [ -z $output ] || [ $output = “” ]
    then
    echo “ERROR WHEN CONNECTING WITH $CURRENTHOST !!!!!!!!”
    else
    if [ $output = “Escape character is ‘^]’.” ]
    then
    echo “CONNECTION OK”
    else
    echo “ERROR WHEN CONNECTING WITH $CURRENTHOST !!!!!!!!”
    fi
    fi
    echo
    echo
    }

    #Function that executes NC on the selected host
    f_executeNC () {
    CURRENTHOST=”$host $port”
    echo “Checking connection with $host:$port”
    $command -v -w ${timeout} -z $host $port
    status=$?
    if [ $status = 0 ]
    then
    echo “CONNECTION OK”
    else
    echo “ERROR WHEN CONNECTING WITH $CURRENTHOST”
    fi
    echo
    echo
    }

    #Function that stops the TELNET processes that have been launched in background and are still active (didn’t connect)
    f_killTimeout () {
    #Check the process is still active and it’s a ‘telnet’
    process=`ps -ef|grep $pid|awk ‘{print $8}’|grep -v grep`
    if [ ! -z $process ]
    then
    if [ “$process” = “telnet” ]
    then
    #Remove this PID from BASH control before killing it, to avoid the ‘Killed…’ message
    disown $pid
    kill $pid
    fi
    fi
    }

    #Function that execute CURL on the selected host
    f_executeCurl () {
    CURRENTHOST=${HOSTS_LIST[$i]}
    echo “Checking connection with $CURRENTHOST”
    $command ${curlParameters[@]} $CURRENTHOST
    status=$?
    if [ $status = 0 ]
    then
    echo “CONNECTION OK”
    else
    if [[ “${ignoredErrors[@]}” =~ “$status” ]]
    then
    echo “CONNECTION OK (ERROR $status IGNORED)”
    else
    echo “ERROR CONNECTING WITH $CURRENTHOST, ERROR MESSAGE: $status !!!!!!!!”
    fi
    fi
    echo
    echo
    }

    #Delete temp files
    f_deleteTemp () {
    rm -f $tempfile
    }

    #Check correct syntax
    f_callCheck () {
    if [ ! $numberParameters -eq 2 ]
    then
    echo “*** Script for Connectivity Testing, version $version ***”
    echo “”
    echo “Syntax:”
    echo “$0 ”
    echo “”
    echo “IMPORTANT: The file must be a complete URL list, each line must be like any of these:”
    echo “protocol://host/path”
    echo “protocol://host:port/path”
    echo “host:port”
    echo “host (when no port is defined, a default one will be used)”
    echo “”
    echo “Accepted commands are: telnet , curl, nc”
    echo “”
    exit 0;
    fi

    if [ ! -f “$file” ]
    then
    echo “ERROR: Can’t find the specified file: $file”
    exit 1;
    else
    IFS=$’\r\n’ HOSTS_LIST=($(cat $file))
    LIST_SIZE=${#HOSTS_LIST[@]}
    fi

    if [ ! $command = “telnet” ] && [ ! $command = “curl” ] && [ ! $command = “nc” ]
    then
    echo “ERROR: Command not supported: $command”
    exit 1;
    fi

    }

    #Initial message
    f_initialMessage () {
    echo
    echo “####################################################”
    echo “### ###”
    echo “### Connectivity Tester, version $version ###”
    if [ $command = “telnet” ]
    then
    echo “### Using TELNET for connection testing ###”
    elif [ $command = “curl” ]
    then
    echo “### Using CURL for connection testing ###”
    else
    echo “### Using NC for connection testing ###”
    fi
    echo “### ###”
    echo “####################################################”
    echo
    echo
    }

    ################
    ## MAIN BLOCK ##
    ################
    f_callCheck
    f_initialMessage
    f_processList
    f_deleteTemp

  11. I updated the script, version 1.6 accepts ‘ping’ too (although port is unused in that case).
    You can find the latest version at http://www.unix.com/shell-programming-and-scripting/255925-check-connectivity-multiple-hosts-bash-script-available-here.html

    Regards,

    • Thanks Fr3dY. Welcome to TechPaste group. Surely lot of people will get benefited from this.

      • Thanks! Hope people find it useful, did u test it?

        Regards,

        • It looks fine, users can use it.

          # ./test.sh curl url.txt

          ####################################################
          ### ###
          ### Connectivity Tester, version 1.6 ###
          ### Using CURL for connection testing ###
          ### ###
          ####################################################

          Checking connection with http://techpaste.com/ Userlogin?screenwidth=1366
          CONNECTION OK

          Checking connection with http://techpaste.com/ Userlogin?screenwidth=1366
          CONNECTION OK

          # ./test.sh ping url.txt

          ####################################################
          ### ###
          ### Connectivity Tester, version 1.6 ###
          ### Using PING for connection testing ###
          ### ###
          ####################################################

          Checking connection with techpaste.com
          CONNECTION OK

          Checking connection with techpaste.com
          CONNECTION OK

          # ./test.sh telnet url.txt

          ####################################################
          ### ###
          ### Connectivity Tester, version 1.6 ###
          ### Using TELNET for connection testing ###
          ### ###
          ####################################################

          Checking connection with techpaste.com:80
          CONNECTION OK

          Checking connection with techpaste.com:80
          CONNECTION OK

  12. Hello!
    Thank you for your script, it’s really useful! I have a question, I want to export the result of the ping test and telnet also with one file containing the server name .
    example:
    ServerName | PingTest | TelnetTest
    serverX | OK | OK
    serverY | OK | NOK
    Have you any idea how I can do that?
    Thanks again!
    Walid

Leave a Reply