inotifywait - beim Umbenennen alten und neuen Dateinamen abrufen

8

Ich suche nach einer zuverlässigen Möglichkeit, das Umbenennen von Dateien zu erkennen und sowohl alte als auch neue Dateinamen abzurufen. Das habe ich bisher:

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

Es funktioniert, aber es wird davon ausgegangen, dass Sie niemals Dateien in den überwachten Ordner oder aus diesem heraus verschieben. Es wird auch davon ausgegangen, dass Ereignisse paarweise auftreten, zuerst verschoben_von, dann verschoben_zu. Ich weiß nicht, ob das immer stimmt (funktioniert bisher).

Ich habe gelesen, dass inotify ein Cookie verwendet, um Ereignisse zu verknüpfen. Ist der Cookie irgendwie zugänglich? Da mir das Cookie fehlte, dachte ich darüber nach, Zeitstempel zu verwenden, um Ereignisse miteinander zu verknüpfen. Gibt es Tipps, wie Sie zuverlässiger von und nach gelangen können?

Vollständiges Skript .

aBe
quelle

Antworten:

6

Ich denke, Ihr Ansatz ist korrekt, und das Verfolgen des Cookies ist ein robuster Weg, dies zu tun. Die einzige Stelle in der Quelle von inotify-tools (3.14), auf cookiedie verwiesen wird , ist jedoch der Header, der structdie Übereinstimmung mit der Kernel-API definiert.

Wenn Sie gerne am Rande leben, gilt dieser Patch ( Problem Nr. 72 ) sauber für 3.14 und fügt einen %cFormatbezeichner für das Ereignis-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 );

Diese Änderung ändert sich libinotifytools.so, nicht die inotifywaitBinärdatei. So testen Sie vor der 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

Angenommen, MOVED_FROM tritt immer vor MOVED_TO auf (es fsnotify_move()ist eine geordnete Warteschlange , obwohl unabhängige Verschiebungen möglicherweise verschachtelt sind). In Ihrem Skript werden die Details zwischengespeichert, wenn eine MOVED_FROM-Zeile angezeigt wird (möglicherweise in einem durch ID indizierten assoziativen Array). und führen Sie Ihre Verarbeitung aus, wenn Sie ein MOVED_TO mit der passenden Hälfte der Informationen sehen.

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

(Da drei Threads ausgeführt werden, um jeweils 10.000 Mal ein Dateipaar zu mischen, habe ich nie ein einzelnes Ereignis außerhalb der Reihenfolge oder eine Verschachtelung von Ereignissen gesehen. Dies kann natürlich vom Dateisystem und anderen Bedingungen abhängen.)

mr.spuratic
quelle
1
Wunderschönen. Ich habe noch nie eine so detaillierte und nützliche Antwort erhalten. Ich danke dir sehr!! Ich denke, die Aufnahme Ihres Patches in die offizielle Version könnte die Erstellung von Tools erleichtern, die dazu beitragen, die Konsistenz zwischen Textdateien (HTML, CSS, MD, ...) und verwiesenen Assets (JPG, GIF, MP4, ...) zu gewährleisten. Senden Sie eine Pull-Anfrage? :)
aBe
Ich hoffe, dass diese Funktion es in die offizielle Version schafft, aber ich habe sie nicht gegabelt, und ich bin nicht sicher, wann ich die Zeit finde, alle Kommentare (doxygen) zu teilen und zu aktualisieren.
mr.spuratic
Wäre echt cool das in Upstream zu bekommen!
Tim Stoop