Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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
share|improve this question
3  
Just 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 Dec 9 '11 at 16:28
    
This 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 Dec 9 '11 at 16:32
    
I don't really see a question with a real answer, maybe this should be moved to the Code Review stack exchange site? –  Caspar Dec 9 '11 at 16:37
    
Ohh, didn't realize such a site existed. Probably should be moved then. –  Sparctus Dec 9 '11 at 16:39

4 Answers 4

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?

share|improve this answer

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...

share|improve this answer

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
share|improve this answer
    
Thanks. I'm having a little trouble understanding. For instance: count=${1:-1} Is this something like a variable assigned to another variable? –  Sparctus Dec 9 '11 at 19:55
    
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 Dec 10 '11 at 1:32

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
share|improve this answer
    
Noted. Thanks for the sugggestion. –  Sparctus Dec 9 '11 at 19:52

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.