get ping reply and store it in bash variable

203 views Asked by At

I am trying to get the number of hops using ping command I used a loop to repeat the command with incremental TTL values but I need to know when the ping succeeds and isn't a "TTL expired in transit" error

success=0
counter=1
while [ $success == 0 ]; do
  echo TTL: $counter
  ping -n 1 google.com -i $counter
  res=$?
  if [[ $res == 0 ]]; then
    success=1
  fi
  ((counter++))
done
echo $counter
2

There are 2 answers

0
Eric Marceau On

You need something like this:

#!/bin/sh
BASE=`basename "$0" ".sh" `
DETAILS="`pwd`/${BASE}.details"

remote="google.com"
attempts="5"
interval="2"
watch="0"

while [ $# -gt 0 ]
do
    case ${1} in
        --host ) remote="$2" ; shift ; shift ;;
        --monitor ) watch="1" ; shift ;;
        --count ) attempts="$2" ; shift ; shift ;;
        --interval ) interval="$2" ; shift ; shift ;;
        * ) echo "\n Invalid parameter used on the command line.  Valid options:  [ --host {} | --count {} | --interval {} | --monitor ]\n Bye!\n" ; exit 1 ;;
    esac
done

if [ ${watch} -eq 1 ]
then
    ping -c ${attempts} -i ${interval} ${remote} | tee "${DETAILS}"
    echo ""
else
    ping -c ${attempts} -i ${interval} ${remote} > "${DETAILS}"
fi

#pingformat
#64 bytes from lga34s34-in-f14.1e100.net (142.250.80.46): icmp_seq=5 ttl=58 time=20.2 ms

grep 'ttl=' "${DETAILS}" | awk -v host="${remote}" 'BEGIN{
    count=0 ;
    tTTL=0 ;
    tRND=0 ;
}{
    if( $1 != 0 ){
        count++ ;

        #Extract TTL
        p=index( $0, "ttl=" ) ;
        rem=substr( $0, p ) ;

        sp=index( rem, " " ) ;
        dat=substr( rem, 1, sp-1 ) ;

        div=index( dat, "=" ) ;
        ttl=substr( dat, div+1 ) ;

        tTTL=tTTL+ttl ;

        #Extract Round Trip Time
        p=index( $0, "time=" ) ;
        rem=substr( $0, p ) ;

        sp=index( rem, " " ) ;
        dat=substr( rem, 1, sp-1 ) ;

        div=index( dat, "=" ) ;
        rnd=substr( dat, div+1 ) ;

        tRND=tRND+rnd ;
    } ;
}END{
    if( count == 0 ){
        printf("\t No response to ping for  %s .\n", host ) ;
    }else{
        printf("\t TTL [avg/%s] = %8.3f\n\t RND [avg/%s] = %8.3f ms for  %s\n", count, tTTL/count, count, tRND/count, host ) ;
    } ;
}'
0
B. Shea On

checkup=$(eval 'ping -4 -c 1 google.com | grep "64 bytes"'); echo $checkup

$checkup stores a string similar to this when it's a normal reply:

64 bytes from ord38s28-in-f14.1e100.net (142.250.191.110): icmp_seq=1 ttl=55 time=13.4 ms

Therefore, if you put something similar in a do/while loop, you could (do something) when $checkup is not equal to a normal reply.

As an example of capturing ping output, this example script should work.