允许Rsync通过python进程读取文件,而python进程失败

时间:2013-05-23 23:06:52

标签: python bash rsync

我正在尝试设置一个邮件日志解析器,它将特定的行拉出到另一个文件中,然后将其rsync到远程服务器。我遇到的问题是当rsync读取正在写入的文件时,它似乎导致解析器停止运行。我相信这是因为解析器正在模拟尾部-f,因为maillog被一致地写入。

所以:我如何允许rsync使用此代码(result_file)触摸我正在编写的文件,同时仍然允许它跟随maillog的末尾寻找新文件:

#! /usr/bin/python

import time, re, sys

result_file = open('/var/log/mrp_mail_parsed.log', 'a+')


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

if __name__ == '__main__':
    logfile = open('/var/log/maillog', 'r')
    logline = tail(logfile)
    for line in logline:
        match = re.search(r'.+postfix-mrp.+', line)
        if match:
            result_file.write(line,)
            result_file.flush()

2 个答案:

答案 0 :(得分:1)

我不知道是谁在写这个文件,或者怎么样,所以我无法确定,但是我会给你的问题提供更好的解决方案:

如果文件未被附加到就地,而是被重写,则代码将停止跟踪该文件。为了测试这个:

import sys
import time

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

with open(sys.argv[1]) as f:
    for line in tail(f):
        print(line.rstrip())

现在:

$ touch foo
$ python tailf.py foo &
$ echo "hey" >> foo
foo
$ echo "hey" > foo

要了解更好的情况,请尝试通过stat检查inode和大小。只要路径引用的文件与脚本打开的文件不同,您的脚本现在就会看到一个其他人无法再触摸的文件。

也有可能有人正在截断并重写文件。这不会改变inode,但它仍然意味着你不会读取任何东西,因为你试图从文件末尾的位置读取。

我不知道rsync的文件是否会导致这种情况,或者这只是巧合。在不知道您正在运行什么rsync命令,或者查看文件是否被替换,或者文件被截断并在该命令运行时被重写时,我们所能做的就是猜测。

答案 1 :(得分:0)

我不相信rsync会导致您的问题:读取文件的单独进程不应该影响编写器。您可以通过暂停rsync来轻松测试。

我猜测问题在于当你点击文件末尾时python处理文件读取。保证工作的原始方法是阅读以记住最后一次EOF中的offest(使用tell())。对于每个新读取,重新打开文件并寻找记住的偏移量。