【问题标题】:Recursive pyinotify watch stops sub-directories from being removed递归 pyinotify watch 阻止子目录被删除
【发布时间】:2015-09-01 18:10:35
【问题描述】:

这是一个奇怪的问题,strace 没有给我任何有用的信息。我正在使用 pyinotify 0.9.6 递归地监视目录,以便我可以将有关它的更改提交到 MySQL 数据库。问题是当我运行 pyinotify 时(无论是否被守护),我可以删除子目录中的文件,但不能删除子目录本身。 rmdir 以状态 0 退出,并且在系统级别上看起来一切正常,但子目录仍然存在,只是令人不寒而栗。我可能只是因为我是框架的新手而变得愚蠢,但这里是我如何初始化手表的示例:

wm = pyinotify.WatchManager()
notifier = pyinotify.Notifier(wm)
wm.add_watch('/path/to/dir', pyinotify.IN_CLOSE_WRITE, rec=True, auto_add=True,\
        proc_fun=CommitFunction() # I can supply this if you think it's relevant
notifier.loop(daemonize=True, callback=None,\
        stdout='/path/to/log.log, stderr='/path/to/log.log')

所以在这个例子中,如果有一个文件 '/path/to/dir/file.txt' 我可以在 'file.txt' 上运行一个 rm 并且它会被删除,但是如果有一个子目录 '/ path/to/dir/subdir' 在 'subdir' 上运行 rm -r 会干净地退出,但该目录实际上并没有被删除。

此外,我的日志没有被写入,但我很确定这是我的错。

编辑:

这是一个 CommitFunction 示例:

class CommitFunction(pyinotify.ProcessEvent):
    def process_default(self, event):
        dir = event.path
        file = event.name
        print "%s is the new file" % os.path.join(dir, file)

EDIT2:实际上我的日志可能没有被写入,因为在提交期间我没有在任何地方调用日志或打印函数。我只是直接写入我的 MySQL 数据库

EDIT3:好的。希望我没有深入研究。这是我在命令行上尝试的:

bash$ cd /var/www
bash$ mkdir subdir
bash$ rmdir subdir
bash$ ls
subdir

这里是实际的提交函数:

class CommitFunction(pyinotify.ProcessEvent):
    def process_default(self, event):
        dir = event.path
        file = event.name
        dbaccess.commit(dir, file) # dir corresponds to a project name

如果您愿意,我可以继续深入,但 dbaccess 具有提交和查询数据库的所有功能(没有真正触及 fs),并且它进一步从定义我的表的“模型”文件中提取。如果有帮助的话,这是一个烧瓶/uwsgi 应用程序

【问题讨论】:

  • 我不知道 CommitFunction 的细节很重要,但是有一个我们可以复制粘贴并运行的示例会很有帮助。
  • 在原始帖子中添加了示例。希望我不会太讨厌。我已经使用这个论坛很多年了,但是当我遇到问题时,我终于不得不创建一个帐户,我找不到答案

标签: python pyinotify


【解决方案1】:

使用此代码:

import pyinotify
import os


class CommitFunction(pyinotify.ProcessEvent):
    def process_default(self, event):
        dir = event.path
        file = event.name
        print "%s is the new file" % os.path.join(dir, file)


wm = pyinotify.WatchManager()
notifier = pyinotify.Notifier(wm)
wm.add_watch('/tmp/testdir', pyinotify.IN_CLOSE_WRITE, rec=True,
             auto_add=True, proc_fun=CommitFunction())
notifier.loop(daemonize=False, callback=None)

我可以在目标目录中创建和删除子目录 没有错误:

bash-4.3$ pwd
/tmp/testdir
bash-4.3$ mkdir subdir
bash-4.3$ rm -r subdir
bash-4.3$ ls
bash-4.3$ 

为了响应上述会话,代码记录了以下内容 标准输出:

/tmp/testdir/subdir is the new file
/tmp/testdir/subdir/ is the new file

您能否确认以上是否表现出您在您的环境中描述的行为?如果没有,您能否用一个完整的示例来更新您的问题?

【讨论】:

  • 奇怪的是,我当时得到了和你一样的结果。现在我更加困惑了。
  • 这就是人们要求Minimal, Complete, and Verifiable examples 的原因,因为如果我们无法重现您的问题,就很难解决。这表明您的实际代码存在问题,或者只是某种还不够的咖啡。
  • 我想你可能是对的,但如果我停止 pyinotify 守护进程(即使 uwsgi 应用程序仍在运行),我就可以成功删除子目录
  • 你能发布一个完整的例子来展示这种行为吗?
  • 是的,让我看看我是否可以在更小的范围内复制它。如果我不能,我会关闭这个话题,并在某个地方接受我自己的愚蠢
【解决方案2】:

好的,所以我遇到的问题是在删除子目录时也会调用 IN_CLOSE_WRITE,这反过来又触发了一个函数,我必须确保在通过网络上传时存在“项目”的目录门户网站。

我还是一头雾水,不过这个问题已经解决了

【讨论】:

    猜你喜欢
    • 2014-05-12
    • 2018-10-15
    • 2010-10-21
    • 2016-04-18
    • 1970-01-01
    相关资源
    最近更新 更多