13

I am trying to use inotifywait to watch all .js files under my ~/js directory; how do I format my regex inside the following command?

$ inotifywait -m -r --exclude [REGEX HERE] ~/js

The regex - according to the man page, should be of POSIX extended regular expression - needs to match "all files except those that ends in .js", so these files can in turn be excluded by the --exclude option.

I've tried the (?!) lookaround thing, but it doesn't seem to work in this case. Any ideas or workarounds? Would much appreciate your help on this issue.

gsklee
  • 4,774
  • 4
  • 39
  • 55

6 Answers6

9

I've tried the (?!) thing

This thing is called negative lookahead and it is not supported by POSIX ERE.

So you have to do it the hard way, i.e. match everything that you want to exclude.

e.g.

\.(txt|xml) etc.

FailedDev
  • 26,680
  • 9
  • 53
  • 73
  • 2
    Is it possible to do it using the [^ ] metachar? I tried .*?[^\.][^j][^s]$ ....... Doesn't work as intended either. – gsklee Oct 30 '11 at 06:19
8

inotifywait has no include option and POSIX extended regular expressions don't support negation. (Answered by FailedDev)

You can patch the inotify tools to get an --include option. But you need to compile and maintain it yourself. (Answered by browndav)

A quicker workaround is using grep.

$ inotifywait -m -r ~/js | grep '\.js$'

But be aware of grep's buffering if you pipe the output to another commands. Add --line-buffered to make it work with while read. Here is an example:

$ inotifywait -m -r ~/js | grep '\.js$' --line-buffered |
    while read path events file; do
      echo "$events happened to $file in $path"
    done

If you just want to watch already existing files, you can also use find to generate the list of files. It will not watch newly created files.

$ find ~/js -name '*.js' | xargs inotifywait -m

If all your files are in one directory, you can also use ostrokach's suggestion. In that case shell expansion is much easier than find and xargs. But again, it won't watch newly created files.

$ inotifywait -m ~/js/*.js
Community
  • 1
  • 1
maikel
  • 1,669
  • 18
  • 15
4

I posted a patch here that adds --include and --includei options that work like negations of --exclude and --excludei:

https://github.com/browndav/inotify-tools/commit/160bc09c7b8e78493e55fc9f071d0c5575496429

Obviously you'd have to rebuild inotifytools, and this is relatively untested, but hopefully it can make it in to mainline or is helpful to someone who comes across this post later.

browndav
  • 41
  • 1
  • I updated the include regex patch a little & added it to Alpine Linux as inotify-tools-inc http://git.alpinelinux.org/cgit/aports/commit/?id=7ee2363baf3fda4d5e66ae285a658b73d1fdd281 – Stuart Cardall Oct 06 '15 at 17:22
  • 1
    Thankfully, your patch or what your patch tried to accomplish is now upstream. When I compiled from the master branch https://github.com/rvoicilas/inotify-tools.git, I see the two options you spoke about. – venkrao May 11 '18 at 07:27
2

Make sure you are quoting the regex command, if you are using shell-relevant characters (including ()).

While this is working:

inotifywait --exclude \.pyc .

this is not:

inotifywait --exclude (\.pyc|~) .

You have to quote the entire regular expression:

inotifywait --exclude '.*(\.pyc|~)' .
sebix
  • 2,943
  • 2
  • 28
  • 43
2

As of version 3.20.1, inotifywait does include the --include and --includei options.

To see them, run inotifywait --help. For some reason, they aren't documented in the manpages.

Guido Tarsia
  • 1,962
  • 4
  • 27
  • 45
1

You could get most of this with --exclude '\.[^j][^s]' to ignore files unless they contain .js at some point in the filename or path. If you combine it with -r then it will work with arbitrary levels of nesting.

Only drawback is filenames like test.js.old will still be watched and all files inside a directory called example.js/ will also be watched, but this is probably somewhat unlikely.

You could probably extend this regex to fix this but personally I don't think the drawbacks are a big enough of a deal to worry about.

Malvineous
  • 25,144
  • 16
  • 116
  • 151