21

In my school, the Internet is not available (every night after 23:00 the school will kill the Internet connection, to put us to bed >..<), Then the ping will never stop, though I have used the parameter ping -w1 ....

That is, when I use: ping -q -w1 -c1 8.8.8.8 to check if the Internet connection is up/down, it will be there without any output and doesn't exit, just like I am using a single cat.

I don't know why it's like this, But I think the problem is related to the school-internet-service. Any suggestion? (I think wget may be a good alternative, but how can I use it?)

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Libin Wen
  • 434
  • 1
  • 5
  • 17

10 Answers10

42

Using wget:

#!/bin/bash
    
wget -q --tries=10 --timeout=20 --spider http://google.com
if [[ $? -eq 0 ]]; then
    echo "Online"
else
    echo "Offline"
fi
alper
  • 2,919
  • 9
  • 53
  • 102
Atropo
  • 12,231
  • 6
  • 49
  • 62
  • It works well. Thank you very much! My old version lacks a `--tries`, thus it doesn't work. – Libin Wen Jun 26 '13 at 03:41
  • 12
    Personally, I enhance this pattern by making this `wget -q --tries=10 --timeout=20 -O - http://google.com > /dev/null`. That throws away the output, which means that files aren't left lying around, and there aren't any problems with write permissions. – Andrew Ferrier Jan 11 '14 at 18:50
  • 6
    You really should use `--spider` option as it will send a http `HEAD` request as opposed to a http `GET` request. Now, in this case you're checking against google.com which is a pretty light weight page so it may be ok as it is. But as a general rule you should use a `HEAD` request if you just want to check if something is available without actually *downloading* it. I've added to the answer accordingly. – peterh Aug 26 '14 at 17:49
23

If the school actually turns off their router instead of redirecting all traffic to a "why aren't you in bed" page, then there's no need to download an entire web page or send HTTP headers. All you have to do is just make a connection and check if someone's listening.

nc -z 8.8.8.8 53

This will output "Connection to 8.8.8.8 port 53 [tcp/domain] succeeded!" and return a value of 0 if someone's listening.

If you want to use it in a shell script:

nc -z 8.8.8.8 53  >/dev/null 2>&1
online=$?
if [ $online -eq 0 ]; then
    echo "Online"
else
    echo "Offline"
fi
Andrew
  • 231
  • 2
  • 2
  • This is the fastest approach, it pings the dns server instead of getting google's website data. thumbs up. – Yoni Dec 03 '15 at 00:51
  • 2
    might be good to use a timeout here nc -z -w 5 8.8.8.8 53 >/dev/null 2>&1 – AShah Nov 02 '18 at 17:50
6

Use:

#!/bin/bash

INTERNET_STATUS="UNKNOWN"
TIMESTAMP=`date +%s`
while [ 1 ]
 do
    ping -c 1 -W 0.7 8.8.4.4 > /dev/null 2>&1
    if [ $? -eq 0 ] ; then
        if [ "$INTERNET_STATUS" != "UP" ]; then
            echo "UP   `date +%Y-%m-%dT%H:%M:%S%Z` $((`date +%s`-$TIMESTAMP))";
            INTERNET_STATUS="UP"
        fi
    else
        if [ "$INTERNET_STATUS" = "UP" ]; then
            echo "DOWN `date +%Y-%m-%dT%H:%M:%S%Z` $((`date +%s`-$TIMESTAMP))";
            INTERNET_STATUS="DOWN"
        fi
    fi
    sleep 1
 done;

The output will produce something like:

./internet_check.sh

UP   2016-05-10T23:23:06BST 4
DOWN 2016-05-10T23:23:25BST 19
UP   2016-05-10T23:23:32BST 7

The number in the end of a line shows duration of previous state, i.e. 19 up, 7 seconds down.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Cyril R
  • 61
  • 1
  • 2
  • Welcome to Stack Overflow! While this code may answer the question, it would be better to include some _context_, explaining _how_ it works and _when_ to use it. Code-only answers are not useful in the long run. – Benjamin W. May 10 '16 at 22:02
  • Had lots of ups and downs in a few minutes. While DropBox was online and surfing the web was possible... See https://unix.stackexchange.com/a/190610/19694 where they mention `nc` would be better to use than ping as quite a few hosters disable ICMP as well. – rhand Mar 26 '19 at 02:00
  • I fail to see how I would get the duration with the code above. I tried it and the 'duration' for each line grew monotonically. Doesn't TIMESTAMP have to be reset each time through the loop? – John Wooten Nov 12 '19 at 16:21
3

Without wget

#!/bin/bash

echo -e "GET http://google.com HTTP/1.0\n\n" | nc google.com 80 > /dev/null 2>&1

if [ $? -eq 0 ]; then
    echo "Online"
else
    echo "Offline"
fi

Enjoy ;)

user3439968
  • 3,418
  • 1
  • 18
  • 15
2

Use the timeout option -t:

ping -q -t 5 -w1 -c1 8.8.8.8 t
suspectus
  • 16,548
  • 8
  • 49
  • 57
  • one problem with this solution is, that some networks might block outgoing pings (my uni had a famous record for doing so). it doesn't seem the be the case with the OP though. – umläute Jun 25 '13 at 07:25
  • @umlaeute, in that case you may use `wget http://google.com` or even (better & simpler) `curl` – Eddy_Em Jun 25 '13 at 07:26
2

Install fping: > fewer problems than ping.

fping google.com | grep alive

To use, for example, like:

#!/bin/bash

itest=$(fping google.com | grep alive)

while [ "$itest" == "" ]
        do
        sleep 5
        itest=$(fping google.com | grep alive)
done
echo now online
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
2

Using the example above. I wrote this script to log the state of your connection: https://gist.github.com/cganterh/ffc2fffa8263857cbece

First, save the following code into a name.sh file.

#!/bin/bash

while true
do
    wget -q --tries=10 --timeout=20 -O - http://google.com > /dev/null
    if [[ $? -eq 0 ]]; then
        echo $(date) "1" | tee -a log.csv
    else
        echo $(date) "0" | tee -a log.csv
    fi
    sleep 5
done

Then, execute name.sh file in terminal, and then check the log state information in log.csv of the same folder.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
1

Reliable old ping in a separate Bash script:

#!/bin/bash
ipaddr='8.8.8.8' # Google's public DNS server
[[ -z `ping -c1 $ipaddr |& grep -o 'Network is unreachable'` ]] || exit 1
[[ -z `ping -c3 $ipaddr |& grep -o '100% packet loss'` ]] && exit 0 || exit 1

Put this in a separate script. It will handle different network situations as (1) not being connected to a network, (2) connected to the network, but cannot access the Internet (or at least Google), and (3) connected to the Internet.


You may later use the exit code of the script to check connectivity, e.g.

~$ script-name && echo online || echo offline
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Majal
  • 1,635
  • 20
  • 31
1

I decided to combine a few of the previous answers, so I could later create a plot showing ups, downs, and their durations:

#!/bin/bash
#
# pinger is a bash shell script that monitors the network
# status every 15 seconds and records if it is up '1' or down '0'
# into the file log.csv from whence it may be plotted.
#
# author: J. W. Wooten, Ph.D.
# since: 11/12/2019
# version: 1.0
#
TIMESTAMP=`date +%s`
while [ 1 ]
  do
    nc -z -w 5 8.8.8.8 53  >/dev/null 2>&1
online=$?
    TIME=`date +%s`
    if [ $online -eq 0 ]; then
      echo "`date +%Y-%m-%d_%H:%M:%S_%Z` 1 $(($TIME-$TIMESTAMP))" | tee -a log.csv
    else
      echo "`date +%Y-%m-%d_%H:%M:%S_%Z` 0 $(($TIME-$TIMESTAMP))" | tee -a log.csv
    fi
    TIMESTAMP=$TIME
    sleep 15
  done;

This outputs to a CSV file every 15 seconds. Using Excel or Numbers, you can read the file and create a plot which will show when the Internet connection was not available and also the duration. If it changes from your sleep interval, then it is spending time trying to connect. I hope to add the ability to send me a text when it detects network is down next.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
John Wooten
  • 685
  • 1
  • 6
  • 21
1

A variation on Majal's solution is just to test the return code from ping, which returns 0 if the site responds, 1 if there is no reply and 2 if the network is unreachable.

    ping -c 1 -t 5 8.8.8.8 2&>1
    rc=$?
    [[ $rc -eq 0 ]] && { echo "Connected to the Internet" ; exit 0 ; } \
 || [[ $rc -eq 1 ]] && { echo "No reply from Google DNS" ; exit 1 ; } \
 || [[ $rc -eq 2 ]] && { echo "Network unreachable" ; exit 2 ; }

Using ping has the advantage of not needing to download anything, improving the speed of the test.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Scooby-2
  • 167
  • 4