每当在目录中创建一个文件时,我该如何运行一个Python脚本?

所以,我正在尝试做这个有点简单的任务,但是我还没有成功。希望现在能改变。
目标:
每当在“/var/www/lager-scanner/filer/Nav/FromNav”中有一个新文件时,以“www-data”用户身份运行“/var/www/lager-scanner/filer/pluk_script.py”。
有人可以告诉我如何做吗?
“/var/www”中的所有文件夹都归“www-data”用户和组所有,并具有“775”权限。

你考虑过使用inotify吗?https://pypi.python.org/pypi/inotify - MadMike
是的,但我不知道如何开始,找不到足够详细的指南让我能够跟随。 - Folkmann
http://askubuntu.com/a/546264/158442 - muru
嗨,Folkmann,你注意到答案了吗? - Jacob Vlijm
是的,我只是还没有时间尝试并回复。 - Folkmann
嗨@Folkmann,你能告诉我你什么时候可以尝试回答吗?我宁愿不让问题一直处于未解决的状态。 - Jacob Vlijm
抱歉,我现在非常忙,所以在6月20日或21日之前可能无法尝试。 - Folkmann
2个回答

不是重复的问题,但在这个问题的被接受答案中,解释了如何在任意目录中添加或创建文件时运行脚本(或任何命令)。在你的情况下,唯一需要的事件触发器是:
-e create

此外,由于您没有将文件路径作为参数使用,您可以跳过--format部分。
然后,在后台运行的脚本只需是:
#!/bin/bash
DIR="/var/www/lager-scanner/filer/Nav/FromNav"
inotifywait -m -r -e create "$DIR" | while read f

do
    # you may want to release the monkey after the test :)
    echo monkey
    # <whatever_command_or_script_you_liketorun>
done

解释

如链接问题所述:

-e create

将会注意到目录中新创建的文件。

选项:

-m -r 

要使命令无限期地(“监视”)在目录中递归运行。

根据this,使用pyinotify并不是最佳选择。

编辑

在评论中,您提到它不起作用,并且您提到目标文件夹是远程的。虽然不完全相同,但问题似乎与this有关:
更改对内核不可见;它完全在远程发生。

一个(经过测试的)解决方法是将远程文件夹挂载到本地。


1所以我终于有时间来尝试这个了 :) 我看了链接的问题并按照步骤操作,但是它不起作用 :/ 它只输出 正在设置监视器。请注意:由于给出了 -r 参数,可能需要一些时间!监视器已建立。 然后就停在那里了。你有什么想法,我做错了什么吗?它甚至没有回显 monkey :/ - Folkmann
我正在参加一个会议,希望在午夜之前能回家 :) 有个傻问题,你试过添加文件吗? - Jacob Vlijm
嗯 :) 仍然没有任何东西 - Folkmann
@Folkmann 等一下,你是移动文件还是创建一个新文件?几乎没有什么可能会不起作用的选项。 - Jacob Vlijm
我创建了一个。它正在监视的文件夹是一个Samba共享文件夹。 - Folkmann
嗨 @Folkmann,我更新了我的回答。 - Jacob Vlijm
嗯,我想我只能创建一个尽可能频繁地运行的cronjob :) 谢谢你的尝试,我猜我应该提到它是被监视的一个远程文件夹挂载为子文件夹 :/ - Folkmann
我必须安装inotify-tools才能使其正常工作。 - Islam Q.

以下是从PyPI inotify页面上修剪过的示例的简化版本(https://pypi.python.org/pypi/inotify),以帮助您入门:
import inotify.adapters
import os

notifier = inotify.adapters.Inotify()
notifier.add_watch('/home/student')

for event in notifier.event_gen():
    if event is not None:
        # print event      # uncomment to see all events generated
        if 'IN_CREATE' in event[1]:
             print "file '{0}' created in '{1}'".format(event[3], event[2])
             os.system("your_python_script_here.py")

它创建了一个Inotify对象,然后使用add_watch()方法添加要监视的目录。接下来,它使用event_gen()方法从Inotify对象创建一个事件生成器。最后,它遍历该生成器。 现在,对监视目录产生影响的文件操作将生成一个或多个事件。每个事件都采用四个值的元组形式:
  • _INOTIFY_EVENT元组(为了清晰起见,在下面的输出中省略)
  • 描述事件的字符串列表
  • 受影响的目录名称
  • 受影响的文件名称
取消注释上述示例中的第一个打印语句并在监视目录中创建文件'new',将得到以下输出:
( (...), ['IN_CREATE'], '/home/student', 'new')    
在'/home/student'中创建了文件'new'
( (...), ['IN_ISDIR', 'IN_OPEN'], '/home/student', '')
( (...), ['IN_ISDIR', 'IN_CLOSE_NOWRITE'/home/student', '')
( (...), ['IN_OPEN'], '/home/student', 'new')
( (...), ['IN_ATTRIB'], '/home/student', 'new')
( (...), ['IN_CLOSE_WRITE'], '/home/student', 'new')
由于'IN_CREATE'事件发生在创建新文件时,这是您可以添加任何要运行的代码的地方。

2os.system真的是非常老式、过时的,不应再使用了。 - Jacob Vlijm