I need some help with a python script

rado84

Well-Known Member
Joined
Feb 25, 2019
Messages
778
Reaction score
634
Credits
4,929
Yesterday there was a major catastrophe with my ISP (my computer ISP and the mobile ISP are different) and we didn't have home internet for over 16 hours. So I decided to modify a script a friend wrote for me which to check for internet connection every 15 minutes and depending on the result to display a message in a dialog window.
But the script keeps showing there's no internet connection even now when there is. I took the command from the internet and I can't seem to make it work. I wanna have this script working for the next time the connection dies, as rare as it may be. The problem is that I do have internet connection now, but the script keeps displaying that there isn't, so obviously I'm missing something or doing something wrong.

The basic idea of the script was to ping a local server with just one packet - far from enough to overload the server and yet more than enough to find out whether there's internet connection and its condition.

On top of that, if I run the script through "Automatically started programs", it displays the dialog window twice at once - you click OK to close the message and it turns out there's the same window under it, so you have to click OK again and I can't see a reason why this is happening. The original script - the one that my friend wrote for me - it doesn't do that. So, if you have any suggestions why the second window, that would be great.

Here's the script I modified:

Code:
#!/bin/bash
while [ 0 -eq 0 ]
do
        packet=$(ping -c 1 abv.bg | grep "packet loss")
    if [ "packet loss" == 0% ]
    then
            echo "Internet connection is OK!"
    else
            zenity --info --text "No connection. I'll try again in 15 minutes." --width="400" --title="Internet check"
    fi
    timeout 900
done

And here's the original script my friend wrote for me, in case you need to see it:

Code:
#!/bin/bash
while [ 0 -eq 0 ]
do
    CHECK="$(curl -s https://archlinux.org/packages/extra/x86_64/nvidia/ | grep '<h2>nvidia')"
    CHECK2="$(echo $CHECK | sed 's/<h2>//g' | sed 's/<\/h2>//g')"
    CHECK3="$(echo $CHECK2 | wc -m)"
    if [ $CHECK3 -ge 19 ]
    then
            echo "$CHECK2, I'll check again in a week."
    else
            zenity --info --text "A stable nvidia driver is available!\n<b>$CHECK2</b>" --width="400" --title="nvidia driver check"
    fi
    sleep 604800
done
 


FYI - Your code examples are bash scripts/shell-scripts NOT python.

The main problem in your code is this line:
Bash:
if [ "packet loss" == 0% ]
You're comparing a string literal "packet loss" against 0% - which will be an undeclared variable.
I would have expected that to cause bash to throw some kind of error message.

This should work:
Bash:
#!/usr/bin/env bash

while :
do
  packetLoss="$(ping -c 1 abv.bg | \grep 'packet loss' | awk '{print $7}')"
  if [ "$packetLoss" == "0%" ]
  then
    echo "Internet connection is OK!"
  else
    zenity --info --text "No connection. I'll try again in 15 minutes." --width="400" --title="Internet check"
    fi
    sleep 900
done

The above uses your ping command, then pipes the result to \grep to isolate the line containing the "packet loss" statistics (NOTE: Using a backslash to escape any aliases that might be set for grep, to ensure that we just get the line without any line-numbers or other unwanted formatting). Then we pipe that to awk and print the field containing the percentage of packets lost/dropped.
The result of those commands is stored in variable packetLoss as a string.
Then we check whether the variable $packetLoss contains the literal string value "0%".

If it does - we know that there was no packet loss and that the internet connection is stable/working.
If not, it means that your connection is either unstable, or completely down. So we use zenity to pop up a dialog on the desktop informing you that your internet connection is down.

However - it's worth pointing out that - because you are only sending one packet - it could be that at that exact moment in time - the ping failed because of some instability in your connection, rather than the connection being completely down.
In order to get a better idea of the state of the internet connection, you could let it send out 5-10 pings and then check the stats.
If packet loss is 0% - your connection is good.
If packet loss is 100% - your connection is completely down
If packet loss is anything in between - it means that your connection is unstable - so you could expand the above slightly to do this:
Bash:
#!/usr/bin/env bash

while :
do
  packetLoss="$(ping -c 10 abv.bg | \grep 'packet loss' | awk '{print $7}')"
  if [ "$packetLoss" == "0%" ]
  then
    echo "Internet connection is OK!"
  elif [ "$packetLoss" == "100%" ]
  then
    zenity --info --text "No Internet connection. I'll try again in 15 minutes." --width="400" --title="Internet check"
  else
    zenity --info --text "Internet connection is unstable, with $packetLoss packet loss! Trying again in 15 minutes." --width="400" --title="Internet check"
  fi
  sleep 900
done

The above will pop up a notification on the desktop if your internet connection is completely down. Or in the case of an unstable connection, will show a notification reporting the instability and the percentage of packets lost.
 
Last edited:
Thanks - for the edit and for the info!
I saw python scripts online somewhere else and they had the same structure of the "if" conditions, that's why I thought this was a python script.
Also I can see you have replaced "timeout" with "sleep". Initially it WAS sleep but since it started popping up every 2 minutes, I changed it to "timeout" because a post on stackoverflow said that sleep doesn't work well in some systems.
I'm not complaining here - no, I'm just saying why it was "timeout". :)

Edit: I just tested the script and it says there's a package loss and it doesn't display how much % loss, but if I run the command outside the script, there don't appear to be any losses:

g9Y5Evh.png


Code:
[rado@arco]: ~>$ ping10 abv.bg
PING abv.bg (194.153.145.104) 56(84) bytes of data.
64 bytes from abv.bg (194.153.145.104): icmp_seq=1 ttl=3 time=1.18 ms
64 bytes from abv.bg (194.153.145.104): icmp_seq=2 ttl=3 time=1.13 ms
64 bytes from abv.bg (194.153.145.104): icmp_seq=3 ttl=3 time=1.13 ms
64 bytes from abv.bg (194.153.145.104): icmp_seq=4 ttl=3 time=1.15 ms
64 bytes from abv.bg (194.153.145.104): icmp_seq=5 ttl=3 time=1.62 ms
64 bytes from abv.bg (194.153.145.104): icmp_seq=6 ttl=3 time=1.31 ms
64 bytes from abv.bg (194.153.145.104): icmp_seq=7 ttl=3 time=1.14 ms
64 bytes from abv.bg (194.153.145.104): icmp_seq=8 ttl=3 time=1.24 ms
64 bytes from abv.bg (194.153.145.104): icmp_seq=9 ttl=3 time=1.31 ms
64 bytes from abv.bg (194.153.145.104): icmp_seq=10 ttl=3 time=1.02 ms

--- abv.bg ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 9013ms
rtt min/avg/max/mdev = 1.021/1.222/1.615/0.155 ms
 
Last edited:
There's the GNU manual for bash:
Which might be a bit of a dry read! But it's the official documentation for bash.
And some other free books here, that might be a little more friendly for people starting out with bash:
Advanced bash scripting guide -
https://tldp.org/LDP/abs/html/ - online version
or
https://tldp.org/LDP/abs - to choose a different format

The Linux Command Line - http://linuxcommand.org/tlcl.php

They might be better starting points, but the bash manual is also worth having as a reference!

Edit: a few more
Bash beginners guide:

The Bash Guide:

Vivek Gite's "Linux Shell Scripting Tutorial":
 
Edit: I just tested the script and it says there's a package loss and it doesn't display how much % loss, but if I run the command outside the script, there don't appear to be any losses:

Ah, ok - the problem is the awk. Change the {print $7} to {print $6} instead. Looks like I remembered the packet stats output from ping incorrectly!
It’s the 6th field that we need to capture, not the 7th field!
I’m on my phone ATM, not near a terminal. Ha ha!
 

Staff online

Members online


Top