python - 允许 Rsync 读取 python 进程打开的文件,而不会导致 python 进程失败

标签 python bash rsync

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

那么:如何允许 rsync 接触我用此代码编写的文件(result_file),同时仍然允许它跟随邮件日志的末尾寻找新文件:

#! /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()

最佳答案

我不知道谁在编写该文件,也不知道如何编写该文件,所以我不能确定,但​​我很可能认为您的问题是这样的:

如果文件没有被就地追加,而是被重写,您的代码将停止跟踪该文件。要测试这一点:

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 命令,也不知道该命令运行时文件是否被替换或文件是否被截断和重写,我们所能做的就是猜测。

关于python - 允许 Rsync 读取 python 进程打开的文件,而不会导致 python 进程失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16725321/

相关文章:

linux - 如何更改 Rsync 服务器上的文件历史记录

ruby - 将文件夹从 server1 复制到 server2 从 localhost linux 运行脚本

linux - rsync 使用包含选项仅复制某些类型的文件

python - Lambda 层中的自定义函数失败,无法将张量转换为 numpy

python - Tornado WebSocketHandler 不会响应 SSL 请求

python - 将 timedelta 转换为总秒数

bash - 如何在单引号文本中显示单引号

python - 如何添加具有所需数量的点的叠加?

bash - 如何按时间而不是大小对 shell 脚本输入进行分块?

bash - 在自动完成目录名称时,如何让 bash 忽略模式(例如 .svn)文件夹?