测试stdin中的新行

时间:2014-11-16 00:38:15

标签: python

我有一个程序通过stdin不断地将状态信息传递给python脚本。它们由一个新行分隔,因此一个更新是stdin中的一个新行。

在我的Python脚本中,我有一个无限循环,等待来自stdin的新输入,然后进行一些后期处理。我希望只要stdin有新信息,但至少5秒钟后就会发生这种后处理。

目前我有:

line = ""
while True:
    if sys.stdin in select([sys.stdin], [], [], 5)[0]:
        line = sys.stdin.readline().strip()
        do_something(line) # do this only if something can be read from stdin

    # do this in any case every 5 secs
    # (but does rely on the most recent info from stdin)
    do_more(line)

如果在stdin可以获得新的更新之前完成一次循环迭代,那么这很有用。

但是,如果在脚本处理先前的更新select块5秒而不是立即返回时,将新行写入stdin。此外,如果循环迭代之间的更新select没有超时,则返回false:

sys.stdin in select([sys.stdin], [], [], 0)[0]

我试图用这种方式改变条件:

if not sys.stdin.isatty() or sys.stdin in select([sys.stdin], [], [], 5)[0]:

这适用于检测循环迭代之间的变化,但如果没有新行可用,则会sys.stdin.isatty()阻止,因此永远不会评估select

我真正需要的是一个以非阻塞方式测试stdin缓冲区是否为空的函数。有这样的功能吗?或任何其他方式来实现我想要的?我只对Linux感兴趣,所以可移植性不是问题。

1 个答案:

答案 0 :(得分:1)

缓冲I / O(例如sys.stdin.readline())和select.select不能一起工作,因为缓冲I / O读取太多而不返回所有内容。在os.read(0, ...)返回后,使用sys.stdin.readline()代替select.select读取字节,并根据该值自行完成输入缓冲。