1

嗨,我正在尝试获取

airodump-ng mon0

其中 mon0 是我的无线接口的监控模式。我想连续读取命令的输出而不在特定时间间隔内终止进程

我的代码如下:

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()

似乎程序卡在x = o_file.read()。请帮忙。

4

1 回答 1

0

当同时设置两者时stdout=subprocess.PIPEstderr=subprocess.PIPE存在死锁的风险(除非您使用communicate同时读取两个通道),因为如果进程写入标准错误并且您尝试读取标准输出,则两者都会永远阻塞。

在你的情况下,你想控制阅读,所以communicate不是一个选择。我怀疑您只想合并两个流,因此请更改:

stderr=subprocess.PIPE

经过

stderr=subprocess.STDOUT

将标准错误重定向到标准输出并获取所有输出+错误o_file.stdout

除了:for i in [1, 2, 3, 4 ,5]:会更像“pythonic”:for _ in range(5):因为你没有使用i,并且还想象你想要循环10000次:)

但是,如果您的应用程序在所有情况下都没有立即打印行,那并不能解决您的问题,因为read()它是阻塞的,并且您需要它在您想要的时候准确停止,所以我会:

  • 创建流程
  • 创建一个线程来读取循环中的行,并使用共享布尔值来停止读取(因为如果输出缓冲区中有行,杀死进程是不够的)
  • 等一段时间
  • 将布尔值设置为True并终止进程

像这样:

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
于 2017-07-13T04:53:32.090 回答