35

I'm trying to create a function that I can call on a timed basis to check for good ping and return the result so I can update the on-screen display. I am new to python so I don't fully understand how to return a value or set a variable in a function.

Here is my code that works:

import os
hostname = "google.com"
response = os.system("ping -c 1 " + hostname)
if response == 0:
    pingstatus = "Network Active"
else:
    pingstatus = "Network Error"

Here is my attempt at creating a function:

def check_ping():
    hostname = "google.com"
    response = os.system("ping -c 1 " + hostname)
    # and then check the response...
    if response == 0:
        pingstatus = "Network Active"
    else:
        pingstatus = "Network Error"

And here is how I display pingstatus:

label = font_status.render("%s" % pingstatus, 1, (0,0,0))

So what I am looking for is how to return pingstatus from the function. Any help would be greatly appreciated.

Totem
  • 7,189
  • 5
  • 39
  • 66
user72055
  • 469
  • 1
  • 6
  • 15
  • 1
    ...`return pingstatus`? – jonrsharpe Oct 20 '14 at 14:54
  • To learn how to call functions and return values, I recommend the [Python Tutorial](https://docs.python.org/3/tutorial/controlflow.html#defining-functions). – Kevin Oct 20 '14 at 14:55
  • At first I was going to suggest a pure-python scheme (without shelling to the underlying OS) but then I saw the hassle/pain in the other thread: https://stackoverflow.com/questions/2953462/pinging-servers-in-python – MarkHu Mar 18 '20 at 21:18

8 Answers8

46

It looks like you want the return keyword

def check_ping():
    hostname = "taylor"
    response = os.system("ping -c 1 " + hostname)
    # and then check the response...
    if response == 0:
        pingstatus = "Network Active"
    else:
        pingstatus = "Network Error"
    
    return pingstatus

You need to capture/'receive' the return value of the function(pingstatus) in a variable with something like:

pingstatus = check_ping()

NOTE: ping -c is for Linux, for Windows use ping -n

Some info on python functions:

http://www.tutorialspoint.com/python/python_functions.htm

http://www.learnpython.org/en/Functions

It's probably worth going through a good introductory tutorial to Python, which will cover all the fundamentals. I recommend investigating Udacity.com and codeacademy.com

EDIT: This is an old question now, but.. for people who have issues with pingstatus not being defined, or returning an unexpected value, first make triple sure your code is right. Then try defining pingstatus before the if block. This may help, but issues arising from this change are for a different question. All the best.

Totem
  • 7,189
  • 5
  • 39
  • 66
  • With this code I get "NameError: name 'pingstatus' is not defined" – user72055 Oct 20 '14 at 15:51
  • 3
    @user72055 While `check_ping` now returns a result, you still need to capture that result by assigning it to a variable before you can access the value: `pingstatus = check_ping()`. – poke Oct 20 '14 at 15:59
  • This does not work on Windows. See [ePi272314](https://stackoverflow.com/a/32684938/3357935) or [Pikamander2's](https://stackoverflow.com/a/39563638/3357935) answer for a multi-platform solution. – Stevoisiak Jun 25 '19 at 16:21
  • The code has an error. pingstatus has to be declared before the if block. Put this line there: pingstatus = None – Shtefan Aug 08 '20 at 03:57
  • @Shtefan Sorry, this is incorrect. Check this out: https://stackoverflow.com/questions/58872704/python-life-variables-in-if-statement – Totem Sep 11 '20 at 11:16
  • @Totem What is incorrect? The variable "pingstatus" is not visible outside of the "if" block. How it can be used for the "return" statement? Have you tried the code before saying "it is incorrect"? – Shtefan Sep 12 '20 at 02:50
  • @Shtefan Hi. Yes, I checked the code, both as a standalone script, and within ipython interpreter. Both cases it works fine. While I don't see anything wrong necessarily in declaring 'pingstatus' before entering the if block, it also doesn't appear to be necessary. So, in my tests, in both cases, 'pingstatus' is visible outside the if block. Did you read the link I posted, it explains that variables assigned inside an if or while, are scoped to the function, class or module, which appears to be the case here. – Totem Oct 02 '20 at 11:58
  • This isn't working, even on Windows with "ping -n 1 host" it always returns 0. – PssstZzz Mar 03 '22 at 00:16
  • @PssstZzz Pls check that your code is right. pingstatus should not return 0 under any circumstance. I added an edit to my answer you might take a look at. – Totem Mar 24 '22 at 15:20
  • `def ping(h): return not(os.system("ping -c 1 " + h))` Or `def ping(h, c=3): return not(os.system("ping -c %s %s >/dev/null" % (c,h)))` Haha – Marki Jan 05 '23 at 17:03
20

Here is a simplified function that returns a boolean and has no output pushed to stdout:

import subprocess
import platform


def ping_ok(sHost) -> bool:
    try:
        subprocess.check_output(
            "ping -{} 1 {}".format("n" if platform.system().lower() == "windows" else "c", sHost), shell=True
        )
    except Exception:
        return False

    return True
alper
  • 2,919
  • 9
  • 53
  • 102
Timothy C. Quinn
  • 3,739
  • 1
  • 35
  • 47
14

Adding on to the other answers, you can check the OS and decide whether to use "-c" or "-n":

import os, platform
host = "8.8.8.8"
os.system("ping " + ("-n 1 " if  platform.system().lower()=="windows" else "-c 1 ") + host)

This will work on Windows, OS X, and Linux

You can also use sys:

import os, sys
host = "8.8.8.8"
os.system("ping " + ("-n 1 " if  sys.platform().lower()=="win32" else "-c 1 ") + host)
Pikamander2
  • 7,332
  • 3
  • 48
  • 69
5

Try this

def ping(server='example.com', count=1, wait_sec=1):
    """

    :rtype: dict or None
    """
    cmd = "ping -c {} -W {} {}".format(count, wait_sec, server).split(' ')
    try:
        output = subprocess.check_output(cmd).decode().strip()
        lines = output.split("\n")
        total = lines[-2].split(',')[3].split()[1]
        loss = lines[-2].split(',')[2].split()[0]
        timing = lines[-1].split()[3].split('/')
        return {
            'type': 'rtt',
            'min': timing[0],
            'avg': timing[1],
            'max': timing[2],
            'mdev': timing[3],
            'total': total,
            'loss': loss,
        }
    except Exception as e:
        print(e)
        return None
sunapi386
  • 1,167
  • 14
  • 18
3
import platform
import subprocess

def myping(host):
    parameter = '-n' if platform.system().lower()=='windows' else '-c'

    command = ['ping', parameter, '1', host]
    response = subprocess.call(command)

    if response == 0:
        return True
    else:
        return False
    
print(myping("www.google.com"))
RexBarker
  • 1,456
  • 16
  • 14
nick
  • 346
  • 2
  • 4
2

I got a problem in Windows with the response destination host unreachable, because it returns 0.

Then, I did this function to solve it, and now it works fine.

import os
import platform

def check_ping(hostname, attempts = 1, silent = False):
    parameter = '-n' if platform.system().lower()=='windows' else '-c'
    filter = ' | findstr /i "TTL"' if platform.system().lower()=='windows' else ' | grep "ttl"'
    if (silent):
        silent = ' > NUL' if platform.system().lower()=='windows' else ' >/dev/null'
    else:
        silent = ''
    response = os.system('ping ' + parameter + ' ' + str(attempts) + ' ' + hostname + filter + silent)

    if response == 0:
        return True
    else:
        return False

Now I can call the command:

print (check_ping('192.168.1.1', 2, False))

The first parameter is the host The second is the number of requests. The third is if you want to show the ping responses or not

0

This function will test ping for given number of retry attempts and will return True if reachable else False -

def ping(host, retry_packets):
    """Returns True if host (str) responds to a ping request."""

    # Option for the number of packets as a function of
    param = '-n' if platform.system().lower() == 'windows' else '-c'

    # Building the command. Ex: "ping -c 1 google.com"
    command = ['ping', param, str(retry_packets), host]
    return subprocess.call(command) == 0

# Driver Code
print("Ping Status : {}".format(ping(host="xx.xx.xx.xx", retry_packets=2)))

Output :

Pinging xx.xx.xx.xx with 32 bytes of data:
Reply from xx.xx.xx.xx: bytes=32 time=517ms TTL=60
Reply from xx.xx.xx.xx: bytes=32 time=490ms TTL=60

Ping statistics for xx.xx.xx.xx:
     Packets: Sent = 2, Received = 2, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
     Minimum = 490ms, Maximum = 517ms, Average = 503ms
Ping Status : True

Note : Change xx.xx.xx.xx with your IP

Shivam Bharadwaj
  • 1,864
  • 21
  • 23
-2

This is my version of check ping function. May be if well be usefull for someone:

def check_ping(host):
if platform.system().lower() == "windows":
response = os.system("ping -n 1 -w 500 " + host + " > nul")
if response == 0:
return "alive"
else:
return "not alive"
else:
response = os.system("ping -c 1 -W 0.5" + host + "> /dev/null")
if response == 1:
return "alive"
else:
return "not alive"
toshiro92
  • 1,287
  • 5
  • 28
  • 42
  • 1
    Python needs indentation to work correctly and this post appears to have lost its indentation. – Kurt Mar 30 '21 at 17:13