8

So, I'm trying to do this, somewhat, simple task, but I have not been successful yet. I'm hoping that changes now.

The goal:

Run /var/www/lager-scanner/filer/pluk_script.py whenever there is a new file in /var/www/lager-scanner/filer/Nav/FromNav, and run this as the www-data user.

Is there someone out there how can tell me how to do that?

All the folders in /var/www are owned by the www-data user and group and have 775 permissions.

Folkmann
  • 193

2 Answers2

8

Not a dupe, but in the accepted answer on this question, it is explained how to run a script (or any command) whenever a file is added or created in an arbitrary directory. In your case, the only needed event- trigger is:

-e create

Furthermore, since you are not using the path to the file as an argument, you can skip the --format -section.

The script to run in the background then simply is:

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

Explanation

As explained in the linked question:

-e create

will notice new files created inside the directory.

The options:

-m -r 

are to make the command run indefinitely ("monitor") and recursively in the directory.

According to this, using pyinotify is not the best option.

EDIT

In a comment you mention it does not work, and you mention the targeted folder is remote. Although not exactly the same, the issue seems related to this:
the change is not visible to the kernel; it happens entirely remotely.

A (tested) work around is to mount the remote folder locally.

Jacob Vlijm
  • 83,767
  • 1
    So I finally had time to try this :) I looked at the linked question and followed, but it doesn't work :/ It just outputs Setting up watches. Beware: since -r was given, this may take a while! Watches established. and stays like that. Any idea what I did wrong? It doesn't even echo monkey :/ – Folkmann Jun 16 '16 at 16:34
  • I am in a conference, hope to be home before midnight :) Silly question, but you tested to add a file ? – Jacob Vlijm Jun 16 '16 at 16:51
  • Jup :) Still nothing – Folkmann Jun 16 '16 at 16:58
  • @Folkmann wait, did you move a file or create one? There is practically no option it wouldn't work. – Jacob Vlijm Jun 16 '16 at 18:10
  • I created one. The folder it is watching is a Samba Shared folder. – Folkmann Jun 16 '16 at 18:51
  • Hi @Folkmann updated my answer. – Jacob Vlijm Jun 17 '16 at 05:41
  • Oh well :/ I guess I'll just create a cronjob that runs as often as I can got it to :) Thanks for trying, guess I should have mentioned it was a remote folder mounted as a subfolder, that was being watched :/ – Folkmann Jun 17 '16 at 13:17
  • I had to install inotify-tools for it to work – Islam Q. Aug 11 '19 at 13:04
2

Here is a trimmed down version of the example from the inotify page on PyPI
(https://pypi.python.org/pypi/inotify) to get you started:

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")

It creates a Inotify object then adds a directory to watch using the add_watch() method. Next it creates a event generator from the Inotify object using the event_gen() method. Finally it iterate overs that generator

Now file operations that affect the watched directory will generate one or more events. Each event takes the form of a tuple with four values:

  • An _INOTIFY_EVENT tuple (omitted in the output below for clarity)
  • A list of strings describing the events
  • The name of the directory affected
  • The name of the file affected

Running the above example with the first print statement uncommented and then creating the file 'new' in the watched directory gives this output:

( (...), ['IN_CREATE'], '/home/student', 'new')    
file 'new' created in '/home/student'
( (...), ['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')

Since the 'IN_CREATE' event occurs when a new file is created, this is where you would add whatever code you wanted to run.

quizdog
  • 121