I'm looking for a reliable way to detect renaming of files and get both old and new file names. This is what I have so far:COUNTER=0;inotifywait -m --format '%f' -e moved_from,moved_to ./ | while read FILEdoif [ $COUNTER -eq 0 ]; then    FROM=$FILE;    COUNTER=1;else    TO=$FILE;    COUNTER=0;    echo sed -i 's/\/$FROM)/\/$TO)/g' /home/a/b/c/post/*.md    sed -i 's/\/'$FROM')/\/'$TO')/g' /home/a/b/c/post/*.mdfidoneIt works, but it assumes you will never move files into or out of the watched folder. It also assumes that events come in pairs, first moved_from, then moved_to. I don't know if this is always true (works so far).I read inotify uses a cookie to link events. Is the cookie accessible somehow?Lacking the cookie, I thought about using timestamps to link events together. Any tips on getting FROM and TO in a more reliable way?Full script gist.
inotifywait - get old and new file name when renaming
linux;shell script;inotify
I think your approach is correct, and tracking the cookie is a robust way of doing this.However, the only place in the source of inotify-tools (3.14) that cookie is referenced is in the header defining the struct to match the kernel API. If you like living on the edge, this patch (issue #72) applies cleanly to 3.14 and adds a %c format specifier for the event cookie in hex:--- libinotifytools/src/inotifytools.c.orig     2014-10-23 18:05:24.000000000 +0100+++ libinotifytools/src/inotifytools.c  2014-10-23 18:15:47.000000000 +0100@@ -1881,6 +1881,12 @@                        continue;                }+               if ( ch1 == 'c' ) {+                       ind += snprintf( &out[ind], size-ind, %x, event->cookie);+                       ++i;+                       continue;+               }+                if ( ch1 == 'e' ) {                        eventstr = inotifytools_event_to_str( event->mask );                        strncpy( &out[ind], eventstr, size - ind );This change modifies libinotifytools.so, not the inotifywait binary. To test before installation:LD_PRELOAD=./libinotifytools/src/.libs/libinotifytools.so.0.4.1 \  inotifywait  --format=%c %e %f -m -e move /tmp/testSetting up watches.Watches established.40ff8 MOVED_FROM b40ff8 MOVED_TO aAssuming that MOVED_FROM always occurs before MOVED_TO (it does, see fsnotify_move(), and it's an ordered queue, though independent moves might get interleaved) in your script you cache the details when you see a MOVED_FROM line (perhaps in an associative array indexed by ID), and run your processing when you see a MOVED_TO with the matching half of the information.declare -A cacheinotifywait  --format=%c %e %f -m -e move /tmp/test |while read id event file; do    if [ $event = MOVED_FROM ]; then        cache[$id]=$file    fi    if [ $event = MOVED_TO ]; then        if [ ${cache[$id]} ]; then            echo processing ...            unset cache[$id]        else            echo mismatch for $id        fi    fidone(With three threads running to shuffle a pair of files each 10,000 times, I never saw a single out of order event, or event interleaving. It may depend on filesystem and other conditions of course.)