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