0

I'm currently working on a Capstone project where my team will be building a network traffic analyzer using Python. But before we can do all that I have to build the baseline for the Command Line Interface. My goal is to make an interface that takes in arguments to initialize, but can take different arguments later from the command line while the script is still running. And so I've encountered a problem. How do I send these argparse variables to another script and change them and send them back?

I've read several StackOverflow answers regarding multiprocessing and shared variables but they never made sense to me for my case.

This is essentially what I'm trying to do:

# parser object
parser = argparse.ArgumentParser(description="A lightweight command-line based Network Traffic Analyzer")

parser.add_argument("-des", "--destination", "-dest", type=str, nargs=1, metavar="destination_ip", default=None, help="Destination IP Address")
parser.add_argument("-s", "--source", type=str, nargs=1, metavar="source_ip", default=None, help="Source IP Address")
parser.add_argument("-pr", "--protocol", type=str, nargs=1, metavar="protocol_name", default=None, help="Type of protocol")
parser.add_argument("-p", "--port", type=str, nargs=1, metavar="port_num", default=None, help="Port Number")
parser.add_argument("-d", "--date", type=int, nargs=1, metavar="date", default=None, help="Date packet was made; Syntax = MMdd")
parser.add_argument("-t", "--time", type=str, nargs=1, metavar="time", default=None, help="Time packet was made; Syntax = HHmm")

args = parser.parse_args()

As you can see, I created arguments for 6 attributes that can be found in a network packet. For now I'm only trying to print off what I'm inputting as a test for future implementations. So I made this function

# Print function. All arguments are sent here and printed
def printargs():
    try:
        while True:
            if args.destination != None:
                print(f"Destination IP is {args.destination[0]}")
            if args.source != None:
                print(f"Source IP is {args.source[0]}")
            if args.protocol != None:
                print(f"Protocol type is {args.protocol[0]}")
            if args.port != None:
                print(f"Port number is {args.port[0]}")
            if args.date != None:
                print(f"Date of packet capture is {args.date[0]}")
            if args.time != None:
                print(f"Time of packet capture is {args.time[0]}")
            clock.sleep(1)
            print("\n")
    except:
        print("Exiting Program...")
        sys.tracebacklimit = 0

So my main question: How can I make it so while this while loop is running, I can have a second script running simultaneously that I can send these variables to, and change them at will so that it prints the new output right away? Do I necessarily have to use Multiprocessing or is there a better/simpler way? Am I overthinking things?

If this is an unrealistic goal, please tell me. Give me any tips at all, because my Python skills are regrettably lacking.

I hope I included enough info to go off of. Thanks for the help!

AerialSong
  • 49
  • 1
  • 7
  • I don't follow. The `args` namespace is available as soon as the `parse_args()` is run, using the `sys.argv` commandline list. There's no looping or iteration involved. – hpaulj Jan 30 '23 at 18:10
  • @hpaulj There is in my case. Because my end goal is to have a command line based network traffic analyzer. Packets upon packets will be printing in real time and I want to be able to change the type of packets that are printed at any time while the script is still running by changing the arguments. Like if I'm printing packets from destination IP 102.90.32.4 for example, then it prints only those for a while, but then I decide I want to look at packets from 203.56.3.11, so I change it. – AerialSong Jan 30 '23 at 18:16

1 Answers1

1

If you want to exchange data between different scripts, you can't do it in principle without multiprocessing, because different scripts are different processes. The easiest way is to make a REST server with Flask as described here: https://www.geeksforgeeks.org/python-build-a-rest-api-using-flask/ In this case you actually don't need the second script, you may use curl.

But if you need to enter data from a command line terminal into a script running in the same terminal, there is another solution. You may use non-blocking input as described here Non-blocking console input? and parse the line entered with argparse.

E.g. for Windows this will look like:

while True:
    time.sleep(1)
    print("I'm working...")
    if msvcrt.kbhit():
        s = sys.stdin.readline()
        print('Entered ', s) # Here you employ argparse

There is the third option: you may use a file as a way to pass arguments. The user echoes new arguments into the file, the script periodically checks if the file exists, and if it does, the script reads the file and deletes it.

aparpara
  • 2,171
  • 8
  • 23