LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Software (https://www.linuxquestions.org/questions/linux-software-2/)
-   -   Ping shell script to report high rtt (https://www.linuxquestions.org/questions/linux-software-2/ping-shell-script-to-report-high-rtt-768162/)

celembor 11-10-2009 06:53 AM

Ping shell script to report high rtt
 
Hi,

I'm trying to write a shell script that makes a ping, with three parameters (IP, count and max rtt), to print the echo response that exceeds the max rtt put as parameter, with a time stamp.

i.e. if I make a ping to 192.168.85.125, with a rtt of 100ms, only prints the echo response that exceeds 100ms:

64 bytes from 192.168.85.125: icmp_seq=4 ttl=128 time=238.39 ms 13:48:34
64 bytes from 192.168.85.125: icmp_seq=12 ttl=128 time=102.19 ms 13:48:54

Really I'm not good at shell scripting, and I'm a few days thinking on it, without a good solution.

any ideas?

Thanks

unSpawn 11-10-2009 03:16 PM

Quote:

Originally Posted by celembor (Post 3751498)
Really I'm not good at shell scripting, and I'm a few days thinking on it, without a good solution.

any ideas?

Post whatever (pseudo)code you got?

celembor 11-19-2009 05:03 AM

Well, I was trying to make something like this (pseudo-code):

make a ping with IP and RTT
read IP and RTT

take time value from each line of echo reply
if time is higher than RTT
print line

---------

In concept it's easy, but I don't know how to create it. I'm not good at shell scripting

Guyverix 11-21-2009 10:26 PM

try something like this then:


ping google.com -i .1 -c 3 | tail -1
This will give you the final line back from three quick pings.

rtt min/avg/max/mdev = 83.148/84.529/85.310/0.979 ms

Now use awk / sed / cut whatever and grab the data you want.

Then just use a if statment and say something along the lines of this maybe..

if [ $RETURN_VALUE -gt <insert threshold here> ]; then
do something
else
everything is good
fi

If you are still learning the basics, try this to format the data in a way that you can use..
run the return data through sed, and change the / character to a space. Now use the awk '{print $#}' to grab the data that you want to compare to your threshold value. If you go about this in this way your print # should be 7-10 depending on how you look at it. Post back if you need more details..

catkin 11-21-2009 11:22 PM

An alternative solution
Code:

#!/bin/bash

echo "$(ping -c3 linuxquestions.org )" | while read
do
    case $REPLY in
        *'time=2'[0-9][0-9]* )
            echo "$REPLY"
    esac
done

EDIT:

Oops! That only catches 200-299 ms outputs :redface:

This is better
Code:

#!/bin/bash

shopt -s extglob

echo "$(ping -c3 linuxquestions.org )" | while read
do
    case $REPLY in
        *'time='[2-9][0-9][0-9]* | *'time='+([0-9])[0-9][0-9][0-9]*)
            echo "$REPLY"
    esac
done


Guyverix 11-22-2009 03:02 AM

Grin, thats a good example, but for someone who is learning scripting, how is he going to make sense of that?

celembor 11-23-2009 10:38 AM

Thank you for this posts.

You're right Guyverix, I don't undertand that script.

Maybe my point of view to perform this script is not right, but I was thinking in something different

command should be something like this:
ping 192.168.1.25 100
and take 100 as max time for echo response. This should make a ping to that IP, and when one of those has a response higher than 100 ms, then it is printed in screen (or file), like this:
64 bytes from 192.168.1.25: icmp_seq=4 ttl=128 time=238.39 ms

thanks for your time

Guyverix 11-24-2009 12:04 AM

So you are thinking more like a continuous ping for an IP and if time is greater than 100 then echo it.
If I were going to code it, I would do something like this then: (this code will not work out of the box, but gives you an idea of the way I am looking at the problem)

# if you do not want this to just run forever, use the -c switch in ping (counts)
#check takes the first arg as an IP address.
#threshold is your second commandline arg.
threshold=$2
check=`ping $1`
while read $check; do
#clean will pull time=###, and sed will strip all A-Z chars, and the =.
clean=`echo $check | awk '{print $7}' | sed 's/[A-Z a-z =]//g'`
if [ $clean -gt $threshold ]; then
echo "Threshold crossed RTT $clean"
fi
done

tacorama 11-24-2009 02:24 AM

i was thinking of something a little simpler
what if you tried to incorporate grep for part of your code...

Quote:

ping google.com | grep time=[1-9][0-9][0-9]
but it fails at 4 digit time values

catkin 11-24-2009 02:38 AM

Quote:

Originally Posted by celembor (Post 3766845)
Thank you for this posts.

You're right Guyverix, I don't undertand that script.

Maybe my point of view to perform this script is not right, but I was thinking in something different

command should be something like this:
ping 192.168.1.25 100
and take 100 as max time for echo response. This should make a ping to that IP, and when one of those has a response higher than 100 ms, then it is printed in screen (or file), like this:
64 bytes from 192.168.1.25: icmp_seq=4 ttl=128 time=238.39 ms

thanks for your time

Change linuxquestions.org to 192.168.1.25 100 and the script I posted does exactly that.

If you want an explanation of how the script works please ask.

unSpawn 11-24-2009 03:13 AM

Quote:

Originally Posted by celembor (Post 3762462)
I'm not good at shell scripting (..) I don't undertand that script.

..and since the OP never posted code he could also benefit from eyeing some basic scripting tutorials like http://www.tldp.org/HOWTO/Bash-Prog-Intro-HOWTO.html, http://www.tldp.org/LDP/Bash-Beginne...tml/index.html (, http://www.tldp.org/LDP/abs/html/ )

celembor 12-02-2009 07:12 AM

Hello,

finally I got what I wanted:
Code:

#!/bin/bash

IP=$1 #Destination address
MAX=$2 #Max time in milisecons to record
SEG="5" #number of seconds for each ping

ping="/bin/ping"

###########################################################
# FUNCTIONS
#
function float_cond()
{
        local cond=0
        if [[ $# -gt 0 ]]; then
                cond=$(echo "$*" | bc -q 2>/dev/null)
                if [[ -z "$cond" ]]; then cond=0; fi
                if [[ "$cond" != 0  &&  "$cond" != 1 ]]; then cond=0; fi
        fi
        local stat=$((cond == 0))
        return $stat
}
###########################################################


while true
do

        RET=`${ping} -c 1 ${IP} | grep 'time=' | awk '{print $7}' | cut -d '=' -f 2`
        if float_cond "${RET} > ${MAX}"; then
                echo "["`date '+%T'`"]: echo reply from ${IP} time=${RET} ms"
                #echo "["`date '+%Y%m%d%k%M%S'`"]  TIME: ${RET}"
        fi
        sleep ${SEG}
done

thanks for your help.


All times are GMT -5. The time now is 04:30 PM.