user5740843
user5740843

Reputation: 1620

Detecting internet for a specific interface over Python

I'm looking for a solution to check whether or not a specific interface (eth0, wlan0, etc) has internet or not.

My situation is as follows; I have 2 active connections. One ethernet connection that has no internet (eth0) and one Wireless connection (wlan0) that has internet. Both have recieved an LAN IP from their respective DHCP servers.

I have come to the conclusion, but I am very open to suggestions, that the best solution would:

Have a ping command:

ping -I wlan0 -c 3 www.google.com

And have Python pick up or not I am able to reach the destination (check for: "Destination Host Unreachable")

import subprocess

command = ["ping", "-I", "wlan0", "-c", "3", "www.google.com"]
find = "Destination Host Unreachable"
p = subprocess.Popen(command, stdout=subprocess.PIPE)
text = p.stdout.read()
retcode = p.wait()

if find in command:
        print "text found"
else:
        print "not found"

This however does not yield the best result, and I could really use some help.

Thanks!

Upvotes: 1

Views: 704

Answers (1)

Padraic Cunningham
Padraic Cunningham

Reputation: 180502

The text variable prints out the pint command output, it's just the finding the text inside the print command output that's not working.

Yes because you don't capture stderr, you can redirect stderr to stdout, you can also just call communicate to wait for the process to finish and get the output:

p = subprocess.Popen(command, stdout=subprocess.PIPE,
                     stderr=subprocess.STDOUT)
out,_ = p.communicate()

You can also just use check_call which will raise an error for any non-zero exit status:

from subprocess import check_call, CalledProcessError, PIPE 

def is_reachable(inter, i, add):
    command = ["ping", "-I", inter, "-c", i, add]
    try:
        check_call(command, stdout=PIPE)
        return True
    except CalledProcessError as e:
        print e.message
        return False

If you want to only catch a certain error, you can check the return code.

def is_reachable(inter, i, add):
    command = ["ping", "-I", inter, "-c", i, add]
    try:
        check_call(command, stdout=PIPE)
        return True
    except CalledProcessError as e:
        if e.returncode == 1:
            return False
        raise

Upvotes: 2

Related Questions