26

I just installed inotify-tools. I would like to continuously detect new file(s) with notify-tools within multiple directories recursively, and send an email using postfix. I can probably handle the send an email using postfix part. I'm just trying to figure out the best way to go about this when trying to detecting new file(s). Because sometimes multiple files are added at once.

3 Answers 3

48
+150

inotifywait (part of inotify-tools) is the right tool to accomplish your objective, doesn't matter that several files are being created at the same time, it will detect them.

Here a sample script:

#!/bin/sh
MONITORDIR="/path/to/the/dir/to/monitor/"
inotifywait -m -r -e create --format '%w%f' "${MONITORDIR}" | while read NEWFILE
do
        echo "This is the body of your mail" | mailx -s "File ${NEWFILE} has been created" "[email protected]"
done

inotifywait will use these options.

-m to monitor the dir indefinitely, if you don't use this option, once it has detected a new file the script will end.

-r will monitor files recursively (if there are a lot of dirs/files it could take a while to detect the new created files)

-e create is the option to specify the event to monitor and in your case it should be create to take care about new files

--format '%w%f' will print out the file in the format /complete/path/file.name

"${MONITORDIR}" is the variable containing the path to monitor that we have defined before.

So in the event that a new file is created, inotifywait will detect it and will print the output (/complete/path/file.name) to the pipe and while will assign that output to variable NEWFILE.

Inside the while loop you will see a way to send a mail to your address using the mailx utility that should work fine with your local MTA (in your case, Postfix).

If you want to monitor several directories, inotifywait doesn't allow it but you have two options, create a script for every dir to monitor or create a function inside the script, something like this:

#!/bin/sh
MONITORDIR1="/path/to/the/dir/to/monitor1/"
MONITORDIR2="/path/to/the/dir/to/monitor2/"
MONITORDIRX="/path/to/the/dir/to/monitorx/"    

monitor() {
inotifywait -m -r -e create --format "%f" "$1" | while read NEWFILE
do
        echo "This is the body of your mail" | mailx -s "File ${NEWFILE} has been created" "[email protected]"
done
}
monitor "$MONITORDIR1" &
monitor "$MONITORDIR2" &
monitor "$MONITORDIRX" &
9
  • I forgot to add several explanations regarding the commands used in the sample script thats the reason to edit my answer... I also added the script in case op wants to monitor several dirs. Regarding inotifywait tool, it is impossible to answer the question without mention it because op is using inotify-tools. By the way, I'm a newbie here so I need to learn a lot regarding netiquette, so, sorry if my answer overlaps yours, it wasn't what i want I just want to give a complete answer to op. Again, sorry.
    – sahsanu
    Aug 18, 2015 at 13:43
  • No problem and welcome to SU. Learning about netiquette is usually done the hard way, as it is not really defined anywhere.
    – harrymc
    Aug 18, 2015 at 14:14
  • 4
    @sahsanu I do not agree about the whole "netiquette" thing. Each person is answering the question from there own perspective. There is no overlap between answers, nor is there an answer that has been rewritten. It is impossible for the answers to differ in that way when the question is so specific. Thank you very much for taking the time to answer the question in great detail. This has helped more than you know, for someone like me who is just learning about all of this. You have saved me countless hours. Aug 18, 2015 at 19:35
  • 1
    @harrymc Netiquetta is defined right here. Aug 18, 2015 at 19:53
  • Netiquette in an evolving environment cannot be absolutely defined.It's customary on this site not to duplicate answers unless they are badly written, and even then it's encouraged to correct them instead via editing. It's always your right in a democratic community not to agree. @sahsanu could have avoided my remark by referring to my previous answer while showing his script, which would have gotten your approval in any case. That's what I would have done in his place and that's my netiquette, which I believe I share with others (but not with everyone, of course).
    – harrymc
    Aug 18, 2015 at 21:11
9

Use inotifywait, for example:

inotifywait -m /path -e create -e moved_to |
    while read path action file; do
        echo "The file '$file' appeared in directory '$path' via '$action'"
        # do something with the file
    done
3
  • 1
    If anyone uses this and convert the variables from the read in uppercase, you won't be able to run some commands inside the while. This is because you would overwrite the $PATH variable.
    – Savageman
    Oct 22, 2015 at 15:51
  • 2
    @Savageman Using uppercase variable names for your own variables is strongly discouraged precisely for this reason. Uppercase variable names are reserved for system use; your own variables should use lowercase.
    – tripleee
    Mar 24, 2016 at 11:40
  • @tripleee Thanks for the info, won't use upper-case vars anymore :)
    – Savageman
    Mar 24, 2016 at 16:05
0

For several directories you can do this:

#!/bin/bash


monitor() {
  inotifywait -m -r -e attrib --format "%w%f" --fromfile /etc/default/inotifywait | while read NEWFILE
  do
     echo "This is the body of your mail" | mailx -s "File ${NEWFILE} has been created" "[email protected]"
  done
          }


monitor &

Here is an example list of folders in the file /etc/default/inotifywait /etc/default/inotifywait

/home/user1
/path/to/folder2/
/some/path/

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .