Lit
Lit

Reputation: 67

Check connection in shell script

I'm using ping for check connection in shell script. The script is like below.

ping -c 1 8.8.8.8 >> log.txt
if [ "$?" == "0" ] ; then
  echo "Success" >> log.txt
else
  echo "Failed" >> log.txt
fi

But sometimes it failed to connect even if network is working well. So I changed -c option to 5 instead of 1.

Then sometimes the log prints like below.

PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=119 time=113 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=119 time=113 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=119 time=114 ms
64 bytes from 8.8.8.8: icmp_seq=5 ttl=119 time=116 ms

--- 8.8.8.8 ping statistics ---
5 packets transmitted, 4 received, 20% packet loss, time 4001ms
rtt min/avg/max/mdev = 113.315/114.555/116.154/1.173 ms

"$?" contains only the result of last try. So even if ping successed 4 times and failed one time at last, script will say connection is failed.

I have an idea about it but cannot write it on shell script because I'm not friendly with it.

If I write it on C++ language, it become like this.

bool result = 1;
for(i=0; i<5; i++)
{
  [try ping and save return code at a]
  result = result&a;
}

if(result)
  cout >> "Success";
else
  cout >> "Failed";

So it means I try ping 5 times and print "Success" if there is one or more return code "0".

How can I do this with shell script?

Upvotes: 1

Views: 2945

Answers (4)

fadil eldin
fadil eldin

Reputation: 143

Multiply the results, break on first 0. otherwise the product is 1

#!/bin/bash

limit=5
iter=1
totalSts=1
echo "Start" > log.txt
while [ $iter -le $limit ]
do
   ping -c 1 8.8.8.8 >> log.txt
   curSts=$?
   echo "iteration" $iter ":" $curSts
   totalSts=$((totalSts * curSts))
   if [ $totalSts -eq 0 ] ; then
     break
   fi
   iter=$((iter+1))
done

if [ $totalSts -eq 0  ] ; then
  echo "Success" >> log.txt
else
  echo "Failed" >> log.txt
fi


   

Upvotes: 1

L&#233;a Gris
L&#233;a Gris

Reputation: 19555

Better with a function

#!/usr/bin/env sh

chk_ping ()
{
  # Set count with argument 1 or default 5
  count=${1:-5}
  # Perform count checks
  while [ $count -gt 0 ]
  do
    count=$(count - 1)
    # If it got a pong, it can return success
    if ping -qn4c1 8.8.8.8 >/dev/null
    then return
    fi
  done
  # It reaches here if all ping checks failed, so return failure
  return 1 # failure
}

if chk_ping 3
then
  echo 'successful ping'
else
  echo 'all pings failed'
fi

Upvotes: 3

cdraper
cdraper

Reputation: 167

The script is saying connection failed because you have an else statement echo "failed" >> log.txt that is telling the script to echo failed if it does. You could possibly do a while read loop that parses that file log.txt and only will throw a "failed" result if, let's say 3 of 5 failed.

#!/bin/bash

ping -c 5 8.8.8.8.8 >> log.txt
if [ "$?" == "0" ] ; then
  echo "Success" >> log.txt
else
  echo "Failed" >> log.txt
fi

# Setting this variable to count the amount of occurances of Success
i=0
while read line
do
if [ $line == "Success" ]; then

        ((i=$i+1))
fi

#Telling bash if 'i' is greater than or equal 3 then it should echo success for the scripts output

if [ $i -ge 3 ]; then

        echo "Ping Script is successful" >> log.txt
else
        echo "Ping Script is failing :(" >> log.txt
fi

done >> log.txt

Please be aware however that since you are appending at the beginning of this script

ping -c 5 10.3.79.150 >> log.txt

This would mean that this file wouldn't be cleared after each run of the script. To avoid this Change:

ping -c 5 10.3.79.150 >> log.txt to ping -c 5 10.3.79.150 > log.txt

Upvotes: 1

souser
souser

Reputation: 6120

You could do the following. Of course, if ping to 8.8.8.8 failed even once, I would say there is an issue somewhere !

status=Failure
for i in 1 2 3 4 5
do
  echo Attempt $i
  ping -c 1 8.8.8.8
  if [ "$?" == "0" ] ; then
    status="Success"
  fi
done
echo Status of ping test = $status

Upvotes: 1

Related Questions