1
\$\begingroup\$

This is the code I made to scan IP addresses. I am new to python and just want to learn how I can optimize it. I know the subprocess is slower than others to IP scanning but if there is a way to make it faster I would like to know how. :)

#!/usr/bin/env python
# coding:utf-8
import subprocess
import datetime
hostname = input("Entrez la gateway de cette manière(example: 192.168.1)")
# Ask for gateway
while True:
    file_name = input("Comment voulez-vous appelez votre dossier?Sans espace ni   caratère spéciaux(example:file_name)")
    # Ask how the user want to name the file where the result of the scan will be

    if " " in file_name:
        print("Réecrire le nom sans espace")
    # check for spaces in the name file(impossible to create name files with spaces or special characters)
    else:
        break
with open(str(file_name) + ".txt", "w")as i:
    i.write("Start time" + str(datetime.datetime.now()))
    # print the start time of the scan process
    for scan in range(1, 255):
        i.write("-" * 100)

        ip_address = str(hostname) + "." + str(scan)
        ping_response = subprocess.Popen(["ping", ip_address, "-n", '1'],   stdout=subprocess.PIPE).stdout.read()
        #Ping the ip address

        ping_response = ping_response.decode()
        # (la réponse du ping est encoder , cette commande la decode)

        print("-"*100)
        print(ping_response)
        i.write(str(ping_response))
        if ip_address == hostname + "." + "254":

            i.write("End time" + str(datetime.datetime.now()))
            # print the end time of the scan process

            i.close()
            quit()
\$\endgroup\$
0
\$\begingroup\$
  1. Use the argparse module for getting user input
  2. Validate user input
  3. Use f"{string}" or "{}".format(string) instead of manually concatting
  4. No need to do i.close() as the with automatically closes the file
  5. Use a if __name__ == '__main__' guard
  6. Add functions for re usability

Revised Code

import subprocess
import datetime
import re

import argparse

def write_result(filename, ping):
    with open(filename, "w") as f:
        f.write(f"Start time {datetime.datetime.now()}")
        for result in ping:
            f.write(result)
        f.write(f"End time {datetime.datetime.now()}")

def ping_subnet(subnet):
    for addr in range(1, 255):
        yield subprocess.Popen(["ping", f"{subnet}.{addr}", "-n", "1"], stdout=subprocess.PIPE) \
                        .stdout.read()                                                          \
                        .decode()

def main(subnet, filename):
    write_result(filename, ping_subnet(subnet))

def parse_arguments():
    parser = argparse.ArgumentParser(usage='%(prog)s [options] <subnet>',
                                     description='ip checker',
                                     epilog="python ipscanner.py 192.168.1 -f somefile.txt")
    parser.add_argument('subnet', type=str, help='the subnet you want to ping')
    parser.add_argument('-f', '--filename', type=str, help='The filename')
    args = parser.parse_args()

    if not re.match(r"(\d{1,3}\.\d{1,3}\.\d{1,3})", args.subnet) \
       or any(a not in range(1, 255) for a in map(int, args.subnet.split("."))):
        parser.error("This is not a valid subnet")

    if " " in args.filename:
        parser.error("There cannot be whitespaces in the filename")

    return args.subnet, args.filename

if __name__ == '__main__':
    main(*parse_arguments())
\$\endgroup\$
  • \$\begingroup\$ First thank you for the precious help! but where am I supposed to declare de subnet when i try to run the code i get this error:usage: labo3.py [options] <subnet> labo3.py: error: the following arguments are required: subnet \$\endgroup\$ – Thewizy Oct 10 '18 at 14:04
  • \$\begingroup\$ try python {scriptname} -h \$\endgroup\$ – Ludisposed Oct 10 '18 at 14:04
  • \$\begingroup\$ Example usage would be python {scriptname} 192.168.1 -f somefile.txt \$\endgroup\$ – Ludisposed Oct 10 '18 at 14:05
  • \$\begingroup\$ Oh ok I understand now, (there's many things I've never used in your code I am going to learn how it works thank you! \$\endgroup\$ – Thewizy Oct 10 '18 at 14:30
  • \$\begingroup\$ Yeah my bad I didn't see the beginner tag, if you have any question feel free to ask them and I will answer as best as I can :) \$\endgroup\$ – Ludisposed Oct 10 '18 at 14:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.