Using inotify to monitor a directory but not working 100%

I have written a bash script to monitor a particular directory /root/secondfolder/:

#!/bin/sh

while inotifywait -mr -e close_write "/root/secondfolder/"
do
    echo "close_write"
done

When I create a file called fourth.txt in /root/secondfolder/ and write stuff to it, save and close it, it outputs the following:

/root/secondfolder/ CLOSE_WRITE,CLOSE fourth.txt

However, it does not echo “close_write”. Why is that?

Asked By: mib1413456

||

inotifywait -m is “monitor” mode: it never exits. The shell runs it and waits for the exit code to know whether to run the body of the loop, but that never comes.

If you remove -m, it will work:

while inotifywait -r -e close_write "/root/secondfolder/"
do
    echo "close_write"
done

produces

Setting up watches.  Beware: since -r was given, this may take a while!
Watches established.
/root/secondfolder/ CLOSE_WRITE,CLOSE bar
close_write
Setting up watches.  Beware: since -r was given, this may take a while!
Watches established.
...

By default, inotifywait will “exit after the first event occurs”, which is what you want in a loop condition.


Instead, you might prefer to read the standard output of inotifywait:

#!/bin/bash

while read line
do
    echo "close_write: $line"
done < <(inotifywait -mr -e close_write "/tmp/test/")

This (bash) script will read each output line of the inotifywait command into the $line variable inside the loop, using process substitution. It avoids setting up the recursive watches every time around the loop, which might be expensive. If you can’t use bash, you can pipe the command into the loop instead: inotifywait ... | while read line .... inotifywait produces one line of output for each event in this mode, so the loop runs once for each.

Answered By: Michael Homer
Categories: Answers Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.