Get output of system ping without printing to the console

前端 未结 2 1683
温柔的废话
温柔的废话 2021-01-05 16:22

I want to call ping from Python and get the output. I tried the following:

response = os.system(\"ping \"+ \"- c\")

However,

相关标签:
2条回答
  • 2021-01-05 16:34

    If you only need to check if the ping was successful, look at the status code; ping returns 2 for a failed ping, 0 for a success.

    I'd use subprocess.Popen() (and not subprocess.check_call() as that raises an exception when ping reports the host is down, complicating handling). Redirect stdout to a pipe so you can read it from Python:

    ipaddress = '198.252.206.140'  # guess who
    proc = subprocess.Popen(
        ['ping', '-c', '3', ipaddress],
        stdout=subprocess.PIPE)
    stdout, stderr = proc.communicate()
    if proc.returncode == 0:
        print('{} is UP'.format(ipaddress))
        print('ping output:')
        print(stdout.decode('ASCII'))
    

    You can switch to subprocess.DEVNULL* if you want to ignore the output; use proc.wait() to wait for ping to exit; you can add -q to have ping do less work, as it'll produce less output with that switch:

    proc = subprocess.Popen(
        ['ping', '-q', '-c', '3', ipaddress],
        stdout=subprocess.DEVNULL)
    proc.wait()
    if proc.returncode == 0:
        print('{} is UP'.format(ipaddress))
    

    In both cases, proc.returncode can tell you more about why the ping failed, depending on your ping implementation. See man ping for details. On OS X the manpage states:

    EXIT STATUS
         The ping utility exits with one of the following values:
    
         0       At least one response was heard from the specified host.
    
         2       The transmission was successful but no responses were received.
    
         any other value
                 An error occurred.  These values are defined in <sysexits.h>.
    

    and man sysexits lists further error codes.

    The latter form (ignoring the output) can be simplified by using subprocess.call(), which combines the proc.wait() with a proc.returncode return:

    status = subprocess.call(
        ['ping', '-q', '-c', '3', ipaddress],
        stdout=subprocess.DEVNULL)
    if status == 0:
        print('{} is UP'.format(ipaddress))
    

    * subprocess.DEVNULL is new in Python 3.3; use open(os.devnull, 'wb') in it's place in older Python versions, making use of the os.devnull value, e.g.:

    status = subprocess.call(
        ['ping', '-q', '-c', '3', ipaddress],
        stdout=open(os.devnull, 'wb'))
    
    0 讨论(0)
  • 2021-01-05 16:38

    To get the output of a command, use subprocess.check_output. It raises an error if the command fails, so surround it in a try block.

    import subprocess
    
    try:
        response = subprocess.check_output(
            ['ping', '-c', '3', '10.10.0.100'],
            stderr=subprocess.STDOUT,  # get all output
            universal_newlines=True  # return string not bytes
        )
    except subprocess.CalledProcessError:
        response = None
    

    To use ping to know whether an address is responding, use its return value, which is 0 for success. subprocess.check_call will raise and error if the return value is not 0. To suppress output, redirect stdout and stderr. With Python 3 you can use subprocess.DEVNULL rather than opening the null file in a block.

    import os
    import subprocess
    
    with open(os.devnull, 'w') as DEVNULL:
        try:
            subprocess.check_call(
                ['ping', '-c', '3', '10.10.0.100'],
                stdout=DEVNULL,  # suppress output
                stderr=DEVNULL
            )
            is_up = True
        except subprocess.CalledProcessError:
            is_up = False
    

    In general, use subprocess calls, which, as the docs describe, are intended to replace os.system.

    0 讨论(0)
提交回复
热议问题