我正在尝试使用这个单线程,它应该打印所有要添加到文件/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:
?
答案 0 :(得分:2)
stdin
已缓冲。
在Python 2中,您可以在启动Python时使用-u
标志禁用缓冲,或者设置PYTHONUNBUFFERED
环境变量。
有一些警告需要注意,但是this answer has the most detail。
答案 1 :(得分:2)
好的,所以这对我有用:
import sys
while True:
print sys.stdin.readline()
使用python -u ...
启动脚本。
我承认托马斯与其他帖子的链接帮助我发现.readline()
应该直接使用-u
才能产生任何效果。
说明:-u
禁用stdin的进程级缓冲(如“标准输入”而不是sys.stdin
对象),并使用.readline()
而不是{{1} }避免for line in sys.stdin
的内部缓冲。
更新关于这个one-liner的问题:“假设翻译人员每隔一秒就会越过这一行sys.stdin
?”......“ “正在观察的一个班轮是:
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())
标志的情况下调用的,所以我无法想象为什么它会在任何系统上可靠地工作,除非该系统上的缓冲语义在Python进程STDIN级别以及执行中都不同-u
。