inotifywait: ottieni il nome del file vecchio e nuovo durante la ridenominazione


8

Sto cercando un modo affidabile per rilevare la ridenominazione dei file e ottenere nomi di file vecchi e nuovi. Questo è quello che ho finora:

COUNTER=0;
inotifywait -m --format '%f' -e moved_from,moved_to ./ | while read FILE
do
if [ $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/*.md
fi
done

Funziona, ma presume che non sposterai mai i file all'interno o all'esterno della cartella controllata. Presuppone anche che gli eventi vengano in coppie, prima spostati da, poi spostati a. Non so se questo è sempre vero (funziona finora).

Ho letto inotify utilizza un cookie per collegare eventi. Il cookie è accessibile in qualche modo? In mancanza del cookie, ho pensato di utilizzare i timestamp per collegare eventi insieme. Qualche consiglio su come ottenere DA e A in un modo più affidabile?

Sintesi completa della sceneggiatura .

Risposte:


6

Penso che il tuo approccio sia corretto e che il monitoraggio dei cookie sia un modo efficace per farlo. Tuttavia, l'unico posto nella fonte di inotify-tools (3.14) a cui si cookiefa riferimento è nell'intestazione che definisce la structcorrispondenza con l'API del kernel.

Se ti piace vivere al limite, questa patch ( numero 72 ) si applica in modo pulito a 3.14 e aggiunge un identificatore di %cformato per il cookie dell'evento in esadecimale:

--- 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 );

Questa modifica modifica libinotifytools.so, non il inotifywaitbinario. Per testare prima dell'installazione:

LD_PRELOAD=./libinotifytools/src/.libs/libinotifytools.so.0.4.1 \
  inotifywait  --format="%c %e %f" -m -e move /tmp/test
Setting up watches.
Watches established.
40ff8 MOVED_FROM b
40ff8 MOVED_TO a

Supponendo che MOVED_FROM si verifichi sempre prima di MOVED_TO (lo fa, vedi fsnotify_move(), ed è una coda ordinata , anche se mosse indipendenti potrebbero essere intercalate) nello script, memorizzi nella cache i dettagli quando vedi una riga MOVED_FROM (forse in un array associativo indicizzato da ID), ed esegui l'elaborazione quando vedi un MOVED_TO con la metà corrispondente delle informazioni.

declare -A cache
inotifywait  --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
    fi
done

(Con tre thread in esecuzione per mescolare una coppia di file ogni 10.000 volte, non ho mai visto un singolo evento fuori servizio o interleaving di eventi. Potrebbe dipendere dal filesystem e da altre condizioni ovviamente.)


1
Bellissimo. Non ho mai ricevuto una risposta così dettagliata e utile prima. Grazie mille!! Penso che l'inclusione della tua patch nella versione ufficiale potrebbe facilitare la creazione di strumenti che aiutano a mantenere la coerenza tra i file di testo (html, css, md, ...) e le risorse di riferimento (jpg, gif, mp4, ...). Stai inviando una richiesta pull? :)
Be il

Spero che questa funzione arrivi alla versione ufficiale, ma non l'ho biforcuta, e non sono sicuro di trovare il tempo per fare fork e aggiornare tutti i commenti (doxygen).
mr.spuratic,

Sarebbe davvero bello avere questo a monte!
Tim Stoop,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.