Bash – Execute command after inotifywait established watches

bashinotifyshellshell-script

Inside shell script (test.sh) I have inotifywait monitoring recursively some direcotry – "somedir":

#!/bin/sh
inotifywait -r -m -e close_write "somedir" | while read f; do echo "$f hi"; done

When I execute this in terminal I will get following message:

Setting up watches.  Beware: since -r was given, this may take a while!
Watches established.

What I need is to touch all files under "somedir" AFTER the watches were established. For that I use:

find "somedir" -type f -exec touch {}

The reason why is that when starting inotifywait after crash, all files that arrived during the time will be never picked up. So the problem and question is, how or when should I execute the find + touch?

So far I have tried to let it sleep few seconds after I call test.sh, but that doesn't work in long run when the number of subdirs in "somedir" will grow.

I have tried to check if the process is running and sleep until it appears, but it seems that process appears before all the watches are established.

I tried to change test.sh:

#!/bin/sh
inotifywait -r -m -e close_write "somedir" && find "somedir" -type f -exec touch {} | 
while read f; do echo "$f hi"; done

But no files are touched at all. So I would really need a help…

Additional info is that test.sh is running in background: nohup test.sh &

Any ideas? Thanks

FYI: Based on advice from @xae, I use it like this:

nohup test.sh > /my.log 2>&1 &
while :; do (cat /my.log | grep "Watches established" > /dev/null) && break; done;
find "somedir" -type f -exec touch {} \+

Best Answer

When inotifywait outputs the string "Watches established." is secure to make changes in the watched inodes, so you should wait to the string to appears on standard error before touching the files.

As an example,this code should to that,

inotifywait -r -m -e close_write "somedir" \
2> >(while :;do read f; [ "$f" == "Watches established." ] && break;done;\
find "somedir" -type f -exec touch {} ";")\
| while read f; do echo "$f hi";done
Related Question