How to display if I was able to ping a machine without displaying the textual pollution of the ping itself?

0

My code is printing out the ping (that polluted screen), but I wanted to print only the "{ip} ta on" pattern.

How do you currently print:

  

PING 192.168.2.1 (192.168.2.1) 56 (84) bytes of data.   64 bytes from 192.168.2.1: icmp_seq = 1 ttl = 64 time = 1.54 ms ...

I want you to print this way;

  

192.168.1.1 ta on

     

192.168.1.2 ta on

     

192.168.1.3 ta off

Code:

import os
os.system('clear')
ip = input('IP INICIAL (192.168.0.1); ').split('.')
print ('Testing...')
for i in range(1,101): # 
    ip[3] = str(i) # 
    ip_formatado = '.'.join(ip) #
    rs = os.system('ping -c 1 {}'.format(ip_formatado)) #
    if rs == 0:
        print ('O {} ta on'.format(ip_formatado))
    
asked by anonymous 03.03.2018 / 03:13

2 answers

1

As Jefferson Quesado commented, Bash is in fact the most appropriate tool for this task, and to do the range is as simple as Python:

#!/usr/bin/env bash

for i in $(seq 1 101); do
    ip="192.168.1.${i}"
    status="$(ping -c 1 "${ip}" | grep "bytes from" && echo "on" || echo "off")"
    echo "${ip} ta ${status}"
done
    
03.03.2018 / 12:12
0

os.system is a direct method, but the crudest of all to execute an external command: it executes the command, but does not give you any control over what the command prints, asks the user, etc ... only returns if there was an error or not.

From the code snippet that is there to understand that you want to be monitoring multiple addresses - using ping in this way also causes the program to wait for the success or failure of each ping - for its 101 addresses, this implies waiting a long time to run all.

The most sophisticated way to call an external process in Python is to use the subprocess module - there are several ways to open an external process - and we want one that: do not even show the output of the commands , and that we can have it run more than one at a time. Since you are using "-c 1", this will not be necessary, but it is even possible for you to do this and be monitoring each separate ping from within Python when you have a more sophisticated program. For now, we can only spend a small timeout (1/20 seconds) - so that the return is almost immediate, and more than enough for a device on a local network to respond:

def principal(ip_base):
    componentes = ip_base.split(".")
    for rede in range(1, 101):
        ip = ".".join((componentes[0], componentes[1], str(rede), componentes[3]))
        try:
            resultado = subprocess.run(
                ["ping", "-c 1", ip,], 
                stdout=subprocess.DEVNULL,
                stderr=subprocess.DEVNULL,
                timeout=0.05
        )
        except subprocess.TimeoutExpired:
            continue
        if resultado.returncode == 0:
            print(f"O Ip {ip} está on")


if __name__ == "__main__":
    ip = input("Base de IP's para monitorar [192.168.0.1]: ")
    if not ip:
        ip = "192.168.0.1"
    principal(ip)

The call to subprocess.run includes the optional parameters for stdout, stderr, and timeout: the first two to be "silenced", and the maximum timeout for timeout. If the timeout passes, it gives an exception - so the try/except : with expired time we pass to the next IP. Check out the subprocess documentation at: link

Note: separating your program into one function: never be too lazy to do this: it's much more readable, easy to change, and expand the program, even if it could be all at the root of the module.

    
03.03.2018 / 12:13