1

Hi I am trying to get output of

airodump-ng mon0

where mon0 is monitor mode of my wireless interface. I want to read the output of the command continuously without killing the process in certain time interval

My code is as follow:

import subprocess
import time

airodump = subprocess.Popen(['airodump-ng','mon0'],stdin=subprocess.PIPE,
                          stdout=subprocess.PIPE,
                          stderr=subprocess.PIPE,
                          universal_newlines=True
                        )
for i in [1, 2, 3, 4 ,5]:
    time.sleep(10)
    o_file = airodump.stdout
    x = o_file.read()
    print(x)
airodump.kill()

It seems like program gets stuck at x = o_file.read(). Please help.

wrufesh
  • 1,379
  • 3
  • 18
  • 36

1 Answers1

1

When setting both stdout=subprocess.PIPE and stderr=subprocess.PIPE there's a risk of deadlock (unless you use communicate to read both channels together), because if the process writes on standard error and you're trying to read standard output, both block forever.

In your case, you want to control the reading, so communicate isn't an option. I suspect that you just want to merge both streams so change:

stderr=subprocess.PIPE

by

stderr=subprocess.STDOUT

to redirect standard error to standard output and get all output+error in o_file.stdout

Aside: for i in [1, 2, 3, 4 ,5]: would be more "pythonic" like: for _ in range(5): since you're not using i, and also imagine that you want to loop 10000 times :)

But that doesn't solve your problem if your application isn't printing the lines at once in all cases, because read() is blocking, and you need it to stop exactly when you want, so I would:

  • create the process
  • create a thread to read the lines in a loop, with a shared boolean to be able to stop the read (because killing the process isn't enough if there are lines in the output buffer)
  • wait some time
  • set the boolean to True & terminate the process

Like this:

import subprocess
import time
import threading

stop_output = False

def f(p):
    global stop_output
    while True:
        l = p.stdout.readline()
        if not l or stop_output:
            break
        print(l.rstrip())   # or whatever you want to do with the line

airodump = subprocess.Popen(['airodump-ng','mon0'],stdin=subprocess.PIPE,
                      stdout=subprocess.PIPE,
                      stderr=subprocess.STDOUT,
                      universal_newlines=True
                    )
t = threading.Thread(target=f,args=(airodump,))
t.start()
time.sleep(10)
# kill the process and stop the display after 10 seconds whatever happens
airodump.terminate()
stop_output = True
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
  • sorry it didnt helped. :( . I placed stderr=subprocess.STDOUT instead of stderr=subprocess.PIPE but it still stucks on read. – wrufesh Jul 13 '17 at 06:31
  • the problem is if process doesn't have anything to read but is still running, it will also be stuck. – Jean-François Fabre Jul 13 '17 at 07:25
  • Hi @jean can you help on this https://stackoverflow.com/questions/45074734/airodump-ng-output-with-python-subprocess-popen-coummunicate-method – wrufesh Jul 13 '17 at 07:59
  • I am trying to achieve the same thing just trying different approach. But nothing is working out. I need data of running airodump-ng in certain interval and use it to display on webpage(updating page on each interval). – wrufesh Jul 13 '17 at 08:06