【问题标题】:How often does sys.stdin generate data?sys.stdin 多久生成一次数据?
【发布时间】:2013-09-23 14:32:33
【问题描述】:

我正在尝试使用这个单行,它应该打印所有添加到文件/var/log/messages.log 中的行。

sudo tail -f /var/log/messages.log | python2 -c 'exec("import sys\n\nfor line in sys.stdin:\n\tprint line")'

为了可读性,python代码为:

import sys

for line in sys.stdin:
        print line

如果我向/var/log/messages.log 添加一行,我看不到任何打印内容。但是,如果我添加大量数据,我就会开始获得输出。

对于生成器sys.stdin 生成data 的频率是否有明确的行为?

PS:我的最终目标是了解one-liner,它输出每秒馈送到python程序的行数。

编辑:如何假设解释器每隔一秒就会越过这条线if t > e:

【问题讨论】:

  • 在我的机器上,链接的单线不能很好地工作。它遇到的问题与您的代码完全相同——报告会延迟到file.next() 的预读缓冲区得到满足。
  • 顺便说一句,这并不是真正的单线。
  • P.S.我已经更新了我的答案,以解释为什么“一个班轮”会以这种方式工作;但是,至少在我的计算机上,它仍然存在相同的输入缓冲问题,就像 @Robᵩ 报告的那样。

标签: python linux pipe generator


【解决方案1】:

好的,这对我有用:

import sys

while True:
    print sys.stdin.readline()

并以python -u ... 启动脚本。

我承认,Thomas 到另一个线程的链接帮助我发现应该直接使用 .readline() 以使 -u 产生任何效果。

解释:-u 禁用 stdin 的进程级缓冲(如在“标准输入”中,而不是具体的 sys.stdin 对象),并且使用 .readline() 而不是 for line in sys.stdin 避免了 @987654331 的内部缓冲@。

更新:至于你对这个one-liner 的问题:“如何假设解释器会每隔一秒越过这条线if t > e:?”... 下的“一个班轮”观察是:

import sys, time
l = 0
e = int(time.time())
for line in sys.stdin:
    t = int(time.time())
    l += 1
    if t > e:
        e = t
        print l
        l = 0

time.time() 以秒为单位返回当前时间为float;将其转换为int 基本上只是将其四舍五入到整秒;第一个时刻int(time.time()) 大于e,也被设置为int(time.time()),几乎正好一秒钟过去了。

但是 sn-p 仍然遭受与原始 sn-p 完全相同的输入缓冲问题;此外,它是在没有-u 标志的情况下调用的,所以我无法想象为什么它会在任何系统上可靠地工作,除非该系统上的缓冲语义在 Python 进程 STDIN 级别以及 @987654341 的实现中都不同@。

【讨论】:

  • 我的部分问题还在于,单线如何完美运行?
  • 重要线索 (docs.python.org/2/library/stdtypes.html#bltin-file-objects) : "为了使 for 循环成为循环文件行的最有效方式(一个非常常见的操作),next()方法使用隐藏的预读缓冲区。作为使用预读缓冲区的结果,将 next() 与其他文件方法(如 readline())结合起来不能正常工作。但是,使用 seek() 将文件重新定位到绝对位置将刷新预读缓冲区。"
  • @shadyabhi: -u 禁用stdin 的进程级缓冲(如在“标准输入”而不是sys.stdin 对象中),并使用.readline() 而不是@987654346 @ 避免了 sys.stdin 的内部缓冲。
  • 谢谢大家。你帮了大忙。
【解决方案2】:

stdin 被缓冲。

在 Python 2 中,您可以通过在启动 Python 时使用 -u 标志或设置 PYTHONUNBUFFERED 环境变量来禁用缓冲。

有一些注意事项需要注意,但this answer has the most detail

【讨论】:

    猜你喜欢
    • 2012-06-21
    • 1970-01-01
    • 2019-09-27
    • 1970-01-01
    • 2011-06-17
    • 2013-05-26
    • 1970-01-01
    • 2014-10-09
    • 1970-01-01
    相关资源
    最近更新 更多