inotifywait - récupère l'ancien et le nouveau nom de fichier lors du changement de nom

8

Je cherche un moyen fiable de détecter le changement de nom des fichiers et d'obtenir les anciens et les nouveaux noms de fichiers. Voici ce que j'ai jusqu'à présent:

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

Cela fonctionne, mais il suppose que vous ne déplacerez jamais de fichiers dans ou hors du dossier surveillé. Il suppose également que les événements se produisent par paires, d'abord move_from, puis move_to. Je ne sais pas si cela est toujours vrai (fonctionne jusqu'à présent).

J'ai lu que inotify utilise un cookie pour lier des événements. Le cookie est-il accessible d'une manière ou d'une autre? Faute de cookie, j'ai pensé à utiliser des horodatages pour relier les événements entre eux. Avez-vous des conseils pour obtenir de et de manière plus fiable?

Contenu essentiel du script .

aBe
la source

Réponses:

6

Je pense que votre approche est correcte, et le suivi du cookie est un moyen robuste de le faire. Cependant, le seul endroit dans la source d'inotify-tools (3.14) qui cookieest référencé est dans l'en-tête définissant le structpour correspondre à l'API du noyau.

Si vous aimez vivre sur le bord, ce correctif ( problème # 72 ) s'applique proprement à 3.14 et ajoute un %cspécificateur de format pour le cookie d'événement en hexadécimal:

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

Ce changement modifie libinotifytools.so, pas le inotifywaitbinaire. Pour tester avant l'installation:

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

En supposant que MOVED_FROM se produit toujours avant MOVED_TO (c'est le cas, voyez fsnotify_move(), et c'est une file d'attente ordonnée , bien que des mouvements indépendants puissent être entrelacés) dans votre script, vous mettez en cache les détails lorsque vous voyez une ligne MOVED_FROM (peut-être dans un tableau associatif indexé par ID), et exécutez votre traitement lorsque vous voyez un MOVED_TO avec la moitié correspondante des informations.

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

(Avec trois threads en cours d'exécution pour mélanger une paire de fichiers chaque 10 000 fois, je n'ai jamais vu un seul événement hors service ou un entrelacement d'événements. Cela peut dépendre du système de fichiers et d'autres conditions bien sûr.)

Mr Spuratic
la source
1
Beau. Je n'ai jamais reçu de réponse aussi détaillée et utile auparavant. Merci beaucoup!! Je pense que l'inclusion de votre patch dans la version officielle pourrait faciliter la création d'outils qui aident à garder la cohérence entre les fichiers texte (html, css, md, ...) et les actifs référencés (jpg, gif, mp4, ...). Envoyez-vous une demande de tirage? :)
aBe
J'espère que cette fonctionnalité sera intégrée dans la version officielle, mais je ne l'ai pas forkée, et je ne sais pas quand je trouverai le temps de forker et de mettre à jour tous les commentaires (doxygen).
mr.spuratic
Ce serait vraiment cool d'avoir ça en amont!
Tim Stoop