使用 Python 在 sdtout 队列中搜索字符串

Searching for strings in sdtout queue using Python

我正在努力了解队列。我正在将 stdout 通过管道传输到队列,然后我想结束管道并在队列中搜索两个字符串。我尝试了下面的方法,但我认为我对队列的理解可能不正确。

这是我的尝试:

alldone = 0
string1found = 0
string2found = 0

MYprocess = subprocess.Popen('adb logact', stdout=subprocess.PIPE)
print "\t\tADB logging on!"

stdout_queue = Queue.Queue()
stdout_reader = AsynchronousFileReader(MYprocess.stdout, stdout_queue)
stdout_reader.start()

MYtimeout = time.time() + duration


while not stdout_reader.eof():
    while not stdout_queue.empty():

        if (time.time() > MYtimeout) and not alldone:
            alldone = 1

if alldone:
    print "Checking log"
    fulllist = stdout_queue.get()
    MYSTRING1 = re.search(r'first string', fulllist)
    MYSTRING2 = re.search(r'second string', fulllist)

    if MYSTRING1:
        string1found = 1
        print 'String 1 found'

    if MYSTRING2:
        string2found = 1
        print 'String 2 found'

我在队列上尝试了 get() 命令,但我认为它只是读取队列的最后一行,所以永远找不到字符串。

Queue.get 从队列中删除并 returns 一项。

您可能想循环直到它为空:

while stdout_queue:
    line = stdout_queue.get()
    # etc

.get()只会return一项,第一项(先进先出!)

您可以像这样将队列读取到列表中,但为什么不直接使用列表开始呢?

def string_in_queue(q):
    while q:
        item = q.get()
        if item == string1:
            return item
    print "String not found"

请注意,这会破坏您的队列,因为 .get() 将从队列中完全删除 项目。

改用列表!

我认为你把这个复杂化了。您不需要 AsynchronousFileReader 或 Queue。这将逐行读取进程输出,在找到字符串时打印出 'found' 消息:

from __future__ import print_function  # For Python 2/3 support

import subprocess

demo_search_strings = (
    (u'String 1', u'Hello'),
    (u'String 2', u'World'),
    )


def main(search_strings):
    # DO NOT use shell=True! I'm ONLY using it here for a quick,
    # undistracting example of a process with delays in output.
    cmd = u'echo Hello World;' + u'sleep 3; echo Hello; sleep 2; echo World;'
    process = subprocess.Popen(cmd * 4, stdout=subprocess.PIPE, shell=True)

    for line in iter(lambda: process.stdout.readline().decode(), ''):
        for ss_name, search_string in search_strings:
            if search_string in line:
                print(u"{ss_name} found".format(ss_name=ss_name))


if __name__ == '__main__':
    main(demo_search_strings)