在没有time.sleep的python中尾部-f

25 python

我需要在python中模拟"tail -f",但我不想在读取循环中使用time.sleep.我想要一些更优雅的东西,如某种阻塞读取,或select.select超时,但python 2.6"选择"文档具体说:"它不能用于常规文件,以确定文件是否自上次读取后增长. " 还有其他方法吗?如果没有给出解决方案,我会在几天内阅读尾部的C源代码以试图找出它.我希望他们不要睡觉,呵呵谢谢.

MarioR

Tzu*_*hay 33

(更新)使用FS监视工具

或单次睡眠使用(我认为你更优雅).

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
Run Code Online (Sandbox Code Playgroud)

  • @ChrisLutz文件增长得越快,额外睡眠就越大.以10行/秒的速度,您无可救药地落后,即使是一个适度繁忙的Web服务器也可以每秒产生数百行. (6认同)

小智 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,
Run Code Online (Sandbox Code Playgroud)


Aar*_*lla 10

从文件中读取时,您唯一的选择就是睡眠(参见源代码).如果您从管道读取,您可以简单地读取,因为读取将阻塞,直到准备好数据.

原因是操作系统不支持"等待某人写入文件"的概念.直到最近,一些文件系统添加了一个API,您可以在其中监听对文件所做的更改,但尾部太旧而无法使用此API,并且它也无法在任何地方使用.


ale*_*gle -3

你为什么不直接使用它subprocess.call自己tail呢?

subproces.call(['tail', '-f', filename])
Run Code Online (Sandbox Code Playgroud)

编辑:修复以消除额外的外壳进程。

Edit2:修复以消除已弃用的情况os.popen,从而消除插入参数、转义空格和其他内容的需要,然后运行 ​​shell 进程。

  • shell命令行解析没有好处。您将 tail 命令、参数和文件名插入到单个字符串中,然后运行 ​​shell 进程再次将它们分开。通过这样做,您还需要自己引用 shell 特殊字符,例如空格(您使用单引号来执行此操作)。那额外的工作不是白费力气吗?如果文件名本身带有引号怎么办?你必须反斜杠转义吗?直接执行 `subprocess.call(['tail', '-f', filename])` 不是更好吗?没有 shell,没有参数连接,因此 shell 可以分割它们,没有引用字符。 (4认同)
  • -1:popen 是错误的方式 - 它调用一个新的 shell 进程,而无需运行 tail 程序。 (2认同)