简体   繁体   English

pyinotify bug与创建时读取文件?

[英]pyinotify bug with reading file on creation?

I want to parse a file everytime a new file is created in a certain directory. 我想在每次在某个目录中创建新文件时解析文件。 For this, I'm trying to use pyinotify to setup a directory to watch for IN_CREATE kernel events, and fire the parse() method. 为此,我正在尝试使用pyinotify来设置目录以监视IN_CREATE内核事件,并触发parse()方法。

Here is the module: 这是模块:

from pyinotify import WatchManager,
    ThreadedNotifier, ProcessEvent, IN_CREATE

class Watcher(ProcessEvent):

    watchdir = '/tmp/watch'

    def __init__(self):
        ProcessEvent.__init__(self)
        wm = WatchManager()
        self.notifier = ThreadedNotifier(wm, self)
        wdd = wm.add_watch(self.watchdir, IN_CREATE)
        self.notifier.start()

    def process_IN_CREATE(self, event):
        pfile = self._parse(event.pathname)
        print(pfile)

    def _parse(self, filename):
        f = open(filename)
        file = [line.strip() for line in f.readlines()]
        f.close()
        return file

if __name__ == '__main__':
    Watcher()

The problem is that the list returned by _parse is empty when triggered by a new file creation event, like so (the file is created in another window while watcher.py is running): 问题是_parse返回的列表在被新文件创建事件触发时为 (如下所示)(该文件在watcher.py运行时在另一个窗口中创建):

$ python watcher.py
[]

...but strangely enough, it works from an interpreter session when called directly. ...但奇怪的是,它直接调用时从解释器会话开始工作。

>>> import watcher
>>> w = watcher.Watcher()
>>> w._parse('/tmp/watch/sample')
['This is a sample file', 'Another line', 'And another...']

Why is this happening? 为什么会这样? The farthest I've come debugging this thing is to know that something is making pyinotify not read the file correctly. 我调试这个东西的最远的地方就是要知道有些东西正在使pyinotify无法正确读取文件。 But... why? 但为什么?

可能你想等到文件关闭?

As @SilentGhost mentioned, you may be reading the file before any content has been added to file (ie you are getting notified of the file creation not file writes). 正如@SilentGhost所提到的,您可能在将任何内容添加到文件之前读取该文件(即,您将收到有关文件创建而非文件写入的通知)。

Update: The loop.py example with pynotify tarball will dump the sequence of inotify events to the screen. 更新:使用pynotify tarball的loop.py示例会将inotify事件序列转储到屏幕上。 To determine which event you need to trigger on, launch loop.py to monitor /tmp and then perform the file manipulation you want to track. 要确定需要触发的事件,请启动loop.py以监视/ tmp,然后执行要跟踪的文件操作。

Here's some code that works for me, with a 2.6.18 kernel, Python 2.4.3, and pyinotify 0.7.1 -- you may be using different versions of some of these, but it's important to make sure we're talking about the same versions, I think...: 这里有一些适合我的代码,2.6.18内核,Python 2.4.3和pyinotify 0.7.1 - 你可能正在使用其中一些版本的不同版本,但重要的是要确保我们谈论的是相同的版本,我认为......:

#!/usr/bin/python2.4

import os.path
from pyinotify import pyinotify

class Watcher(pyinotify.ProcessEvent):

    watchdir = '/tmp/watch'

    def __init__(self):
        pyinotify.ProcessEvent.__init__(self)
        wm = pyinotify.WatchManager()
        self.notifier = pyinotify.ThreadedNotifier(wm, self)
        wdd = wm.add_watch(self.watchdir, pyinotify.EventsCodes.IN_CREATE)
        print "Watching", self.watchdir
        self.notifier.start()

    def process_IN_CREATE(self, event):
        print "Seen:", event
        pathname = os.path.join(event.path, event.name)
        pfile = self._parse(pathname)
        print(pfile)

    def _parse(self, filename):
        f = open(filename)
        file = [line.strip() for line in f]
        f.close()
        return file

if __name__ == '__main__':
      Watcher()

when this is running in a terminal window, and in another terminal window I do 当它在终端窗口中运行时,在另一个终端窗口中我这样做

echo "ciao" >/tmp/watch/c3

this program's output is: 这个程序的输出是:

Watching /tmp/watch
Seen: event_name: IN_CREATE   is_dir: False   mask: 256   name: c3   path: /tmp/watch   wd: 1   
['ciao']

as expected. 正如所料。 So can you please try this script (fixing the Python version in the hashbang if needed, of course) and tell us the exact releases of Linux kernel, pyinotify, and Python that you are using, and what do you observe in these exact circunstances? 那么请你试试这个脚本(当然,如果需要,可以在hashbang中修复Python版本)并告诉我们你正在使用的Linux内核,pyinotify和Python的确切版本,以及你在这些确切的环境中观察到了什么? Quite possibly with more detailed info we may identify which bug or anomaly is giving you problems, exactly. 很可能有更详细的信息,我们可以确定哪个错误或异常正在给你带来问题。 Thanks! 谢谢!

I think I solved the problem by using the IN_CLOSE_WRITE event instead. 我想我通过使用IN_CLOSE_WRITE事件来解决问题。 I'm not sure what was happening before that made it not work. 我不确定之前发生了什么让它无法正常工作。

@Alex: Thanks, I tried your script, but I'm using newer versions: Python 2.6.1, pyinotify 0.8.6 and Linux 2.6.28, so it didn't work for me. @Alex:谢谢,我试过你的脚本,但是我使用的是更新的版本:Python 2.6.1,pyinotify 0.8.6和Linux 2.6.28,所以它对我不起作用。

It was definitely a matter of trying to parse the file before it was written, so kudos to SilentGhost and DanM for figuring it out. 这绝对是在编写文件之前尝试解析文件的问题,所以感谢SilentGhost和DanM搞清楚。

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

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