Restart computer if internet connection goes down

4

2

I'm trying to write a small bash script that checks for internet connection. If no internet is detected, it tries again in another 10 minutes... and if still no internet, it restarts the computer. I've written this thus far. Any ideas to suggest improvement / efficiency / better code is appreciated.

#!/bin/bash
# Script to restart the computer if there is no internet connection 
#   within the next 10 minutes of whenever the script is run, which 
#   I'll setup via crontab to run every half an hour. 

IS=`/bin/ping -c 5 8.8.8.8 | grep -c "64 bytes"`        

if (test "$IS" -gt "2") then                                
        internet_conn="1"
    exit
else
    internet_conn="0"
    sleep 600

    AA=`/bin/ping -c 5 74.125.226.18 | grep -c "64 bytes"`

    if (test "$AA" -gt "2") then                                
        internet_conn="1"
        exit
    else
        sudo shutdown -r now
    fi
fi

Sparctus

Posted 2011-12-09T16:20:57.253

Reputation: 103

3Just curious: What's the point of rebooting when your link goes down ? What do you think will happen when google takes down/recycle that IP and it doesn't return ICMP anymore ? If you want to do that anyway you'd better choose that IP: 8.8.8.8 (google public dns server) – Shadok – 2011-12-09T16:28:23.633

1This computer uses a script to initiate a reverse ssh tunnel. Sometimes, due to network problems, the sockets go stale and active connections through tunnel hang, so a reboot would start everything fresh. As per your suggestion, I've changed the ip. Good catch. – Sparctus – 2011-12-09T16:32:29.290

I don't really see a question with a real answer, maybe this should be moved to the Code Review stack exchange site?

– Caspar – 2011-12-09T16:37:58.830

Ohh, didn't realize such a site existed. Probably should be moved then. – Sparctus – 2011-12-09T16:39:48.837

Answers

2

I think your script should work fine, but you might want to check more places than just one DNS server. Granted, its a big DNS that probably will never go down, but you don't want to reboot your server if they happen to be doing maintenance on that IP so I would check maybe three sources and if they all show as down then restart your server.

Also, might it be more prudent to simply bring interface down and back up rather than reboot?

user194600

Posted 2011-12-09T16:20:57.253

Reputation:

1

Small suggestion, you don't need grep to evaluate if the ping succeeded. Ping exits with 0 if succeeded, and 1 or higher if error occurred. So you could also script it as following. The $? variable shows the return code of the last executed command.

/bin/ping -c 5 8.8.8.8

if ( $? -ge 1); then
 ......
fi

rkokkelk

Posted 2011-12-09T16:20:57.253

Reputation: 11

0

This answer is for those coming in the year 2019 and up:

I tried to use @rkokkelk 's answer, but it doesn't seem to work and the bash documentation confirms that assumption, if I read correctly.

Therefore, I present to you my personal approach (I know it is not efficient, but I wanted it this way):

#!/bin/bash
# Restarts computer after 90 minutes of no internet connection.

/bin/ping -c 20 8.8.8.8

if [ "$(echo $?)" == 1 ]; then
    sleep 15
    /bin/ping -c 20 8.8.4.4

    if [ "$(echo $?)" == 1 ]; then
        sleep 5400

        /bin/ping -c 20 8.8.8.8

        if [ "$(echo $?)" == 1 ]; then
            sleep 15
            /bin/ping -c 20 8.8.4.4

            if [ "$(echo $?)" == 1 ]; then
                shutdown -r now
            else
                exit
            fi
        else
            exit
        fi
    else
        exit
    fi

else
    exit
fi

This works with bash version 4.4.12(1)-release.

Akito

Posted 2011-12-09T16:20:57.253

Reputation: 119

There's no reason to say "$(echo $?)"; just say "$?".  (And, strictly speaking, if you're going to echo $?, you should echo "$?".) – Scott – 2019-02-14T05:07:21.983

@Scott It didn't work the way you propose, that's how I came up with echo in the first place. – Akito – 2019-02-14T21:47:01.437

0

Here's an approach that uses at to reschedule itself in 10 minutes to check again.

#!/bin/bash
count=${1:-1}
if /bin/ping -c 5 8.8.8.8 2>&/dev/null; then                                
    if [ $count -eq 2 ]; then
        sudo shutdown -r now
    else
        at now + 10 minutes <<< "$0 $((count + 1))"
    fi
fi

glenn jackman

Posted 2011-12-09T16:20:57.253

Reputation: 18 546

Thanks. I'm having a little trouble understanding. For instance: count=${1:-1} Is this something like a variable assigned to another variable? – Sparctus – 2011-12-09T19:55:41.637

The :- syntax sets the variable ($1) to the default value ("1") if $1 is empty (user passed the argument "") or unset (user did not provide any arguments). – glenn jackman – 2011-12-10T01:32:57.093

0

Your comment on a reverse ssh tunnel "stalling" after a while is probably due to a NAT router trying too minimize its open connections table and should be resolved by using the "ServerAliveInterval" directive as explained in the OpenSSH FAQ.

In some cases the router/firewall is aggressively pruning you sessions anyway (bad!) when the link is left idle for a long time which forces you to lower the ServerAliveInterval (cf. note).

The trick in this case is to use a sort of wrapper monitoring the ssh daemon and restarting it when necessary, autossh does exactly that, that should solve your problem right away !


note : This is something you want to limit because increasing the frequency of keepalive packets on an unstable link raises the risk of disconnections; which are defined as x keepalive response packets, in reality TCP ACK packets, failed successively.

If your link is reliable feel free to lower that directive to your convenience (be wise, you don't need a keepalive packet per second) to detect more quickly disconnections from the server.


PS: To explain my comment on the question, I'm a bit repulsed by the ideas of using ping as a condition to restart a service and using it on a server you don't own and thus can't guarantee the availability, maybe tomorrow google will decide to stop responding to echo pings and your server will keep rebooting indefinitely.

Another problem is what you define as "internet connection" is by definition a big collection of networks and testing a single end point may be too small to get an idea of your connectivity on the network, that's why monitoring services on the web uses a variety of links to track responses time/uptime/etc...

Shadok

Posted 2011-12-09T16:20:57.253

Reputation: 3 760