我有一个程序通过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感兴趣,所以可移植性不是问题。
答案 0 :(得分:1)
缓冲I / O(例如sys.stdin.readline()
)和select.select
不能一起工作,因为缓冲I / O读取太多而不返回所有内容。在os.read(0, ...)
返回后,使用sys.stdin.readline()
代替select.select
读取字节,并根据该值自行完成输入缓冲。