简体   繁体   English

用Python复制“tail -f”

[英]Replicating “tail -f” with Python

According to David Beazley's talk on generators , the following code should replicate the UNIX tail -f command: 根据David Beazley关于生成器的讨论 ,以下代码应该复制UNIX tail -f命令:

import time
def follow(thefile):
    thefile.seek(0,2)
    while True:
        line = thefile.readline()
        if not line:
            time.sleep(0.1)
            continue
        yield line

f = open('followed.txt')
lines = follow(f)

for i in lines:
    print i

If I run this in a shell, it's doing "something", and indeed it locks up the IPython notebook, but it ain't printing out the contents of followed.txt. 如果我在shell中运行它,它正在做“某事”,它确实锁定了IPython笔记本,但它没有打印出follow.txt的内容。 Why so? 为什么这样?

I tried the script, it works. 我尝试了脚本,它的工作原理。

You have to make sure your input file is a growing file. 您必须确保输入文件是一个不断增长的文件。 If not it is hanging and expecting new growing lines. 如果没有,它会悬挂并期待新的生长线。

Here's a script keep writing line with timestamp into sample.csv every 5 seconds. 这是一个脚本,每隔5秒就将带有时间戳的行写入sample.csv。

import os
import time
import datetime

while True:
    os.system("echo " + "sample line with timestamp:{0}".format(datetime.datetime.now()) + " >> " + " sample.csv")
    time.sleep(5)

Use your tail -f script to read it and you will see the output. 使用tail -f脚本读取它,您将看到输出。

The follow() generator is only going to return lines that are written to the file after follow() was called. follow()生成器只会在调用follow() 返回写入文件的行。 The seek(0,2) puts the cursor at the end of the file, and then tries to read new lines from that point on. seek(0,2)将光标放在文件的末尾 ,然后尝试从该点开始读取新行。

tail usually outputs the last 10 lines by default. tail通常默认输出最后10行。 If you wanted something like that 如果你想要那样的话

def follow(thefile):
    n_lines = 0
    # Seek to the end of the file
    thefile.seek(0,2)
    # Seek the cursor back one character at a time until you
    # reach the beginning of the file or 10 newlines are found.
    while n_lines < 10 and thefile.tell() > 0:
        # Go back one character and read it.
        thefile.seek(-1, 1)
        c = thefile.read(1)
        # Only go back 10 lines
        if c == '\n':
            n_lines += 1:
        # Reset the cursor position for the character we just read
        thefile.seek(-1, 1)

    while True:
        line = thefile.readline()
        if not line:
            time.sleep(0.1)
            continue
        yield line

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM