在Python中实现无time.sleep的tail -f
我想在Python中模拟“tail -f”这个功能,但我不想在读取循环中使用time.sleep。我想要一种更优雅的方法,比如某种阻塞读取,或者使用select.select加上超时,但Python 2.6的“select”文档明确说:“它不能用于常规文件,以判断文件自上次读取以来是否有增长。”有没有其他的方法呢?
如果几天内没有解决方案,我就打算去看一下tail的C源代码,试着弄明白。我希望他们没有用sleep,嘿嘿。
谢谢。
MarioR
10 个回答
10
在从文件读取数据时,你唯一的选择就是让程序“睡觉”(查看源代码)。如果你是从管道读取数据,那就简单多了,因为读取操作会一直等着,直到有数据可以读取。
之所以这样,是因为操作系统并不支持“等着有人往文件里写数据”这种概念。最近一些文件系统增加了一个可以监听文件变化的接口,但“tail”这个工具太老了,无法使用这个接口,而且这个接口并不是在所有地方都能用。
11
为了减少睡眠问题,我对Tzury Bar Yochay的解决方案进行了修改。现在它会快速检查是否有活动,如果几秒钟内没有活动,它就会每秒检查一次。
import time
def follow(thefile):
thefile.seek(0,2) # Go to the end of the file
sleep = 0.00001
while True:
line = thefile.readline()
if not line:
time.sleep(sleep) # Sleep briefly
if sleep < 1.0:
sleep += 0.00001
continue
sleep = 0.00001
yield line
logfile = open("/var/log/system.log")
loglines = follow(logfile)
for line in loglines:
print line,
34
(更新)
你可以使用文件系统监控工具:
或者你也可以使用一个简单的睡眠函数(我觉得这个方法更优雅)。
import time
def follow(thefile):
thefile.seek(0,2) # Go to the end of the file
while True:
line = thefile.readline()
if not line:
time.sleep(0.1) # Sleep briefly
continue
yield line
logfile = open("access-log")
loglines = follow(logfile)
for line in loglines:
print line