5

Doing an inotifywait to watch a directory, and trying to exclude all subdirectories from being watched while not excluding the files.

inotifywait -r -q --exclude <pattern> dir/

What to put in <pattern>? Manual for inotifywait specifies:

--exclude <pattern>
Do not process any events whose filename matches the specified POSIX extended regular expression, case sensitive.

There's no -type flag like in find. I've tried (^/) but that seems to exclude everything.

Help appreciated.

Sqerstet
  • 701
  • 1
  • 8
  • 22

5 Answers5

6

Since the --exclude option only acts on filenames, there's no direct way to do it. You could try round-about ways like using find to print the name of all directories:

inotifywait --exclude "echo -n (;$(find . -maxdepth 1 -mindepth 1 -type d -printf '%P|');echo )" .

Note that I didn't specify -r, since that will cause newly created subdirectories to be watched too.

This might break with some special characters.


You could also try:

find . -maxdepth 1 -mindepth 1 -type d -printf '@%P\n' > list_of_directories
inotifywait --fromfile list_of_directories .

inotifywait will exclude any files or folders in list_of_directories which begin with @ (all of them do).


If you're using inotifywait with the recursive option, let find list all nested subdirectories as well by removing the -maxdepth restriction (also applies to the first command):

find . -mindepth 1 -type d -printf '@%P\n' > list_of_directories
inotifywait --fromfile list_of_directories . -r

The -mindepth is retained to prevent find from matching ., and thus excluding the current directory as well.

muru
  • 197,895
  • 55
  • 485
  • 740
  • Thanks! But the last version of find will not catch subdirectories within subdirectories, I just tried it to confirm. I need it to catch all directories and ignore all files. In other words, I just want inotifywait to watch changes to files and nothing else. Seemed simple. Oh well. – Sqerstet Nov 03 '14 at 21:53
  • @Sqerstet since I hadn't included the recursive option, that seemed fine. If not, you can simply remove the -maxdepth option to let find find all nested subdirectories. – muru Nov 03 '14 at 21:59
  • Didn't work until I added \n after @%P – brian Nov 08 '18 at 17:47
  • are you sure no directories?.. I just tried this inotifywait -mr --exclude '(.chromium)' -e modify -e create -e delete ~/.config from https://serverfault.com/questions/403874/inotifywait-usage-and-exclude, and it worked. Normally its flooded with junk from Chrome. – alchemy Mar 30 '20 at 22:53
  • @alchemy I think what I meant is that there's no direct regex to exclude subdirectories but include files (e.g., when you're looping on files in a shell, you can do foo*/ to expand only to subdirectories and there's no equivalent here - all that pattern gets is the name, and there's no way to tell from the name whether it's a directory). – muru Mar 31 '20 at 02:49
5

Just use --exclude '/\..+'. This ignores all files that start with a dot.

(The .+ part is so that it does not exclude your base folder).

ostrokach
  • 854
  • 8
  • 11
4

inotifywait only checks subdirectories because of the parameter -r.
Call it without that parameter and it won't watch subdirectories.

Jan
  • 12,291
  • 3
  • 32
  • 38
  • Apologies, my question was not clear. I want to exclude the directories but not the files. Question updated. – Sqerstet Nov 03 '14 at 19:10
1

Try this way:

/usr/bin/inotifywait -mrq --format  '%Xe %w%f' -e modify,create,delete,attrib,close_write,move --exclude '^./workspace' ./ | while read file; do
   # do something
done 

Replace the workspace to your directory name.

Artur Meinild
  • 26,018
1

I can confirm, that --exclude 'node_modules' does the job for me, also if node_modules is a subfolder.

while inotifywait -rqq -e close_write --exclude 'node_modules' "$1"; do $2;$3;$4; done

also tested in this:

inotifywait --recursive --monitor --format "%e %w%f" \
  --event modify,move,create,delete  --exclude 'node_modules'  ./ |
  while read changed; do
    sleep .2 && ./devrun
  done
Frank N
  • 1,340