Wie führe ich einen Befehl aus, wenn der Inhalt eines Verzeichnisses aktualisiert wird?

27

Es gibt ein Verzeichnis, Adessen Inhalt von anderen Personen häufig geändert wird.

Ich habe ein persönliches Verzeichnis erstellt, Bin dem alle Dateien gespeichert sind, die jemals gespeichert wurden A.

Derzeit renne ich nur gelegentlich rsync, um die zu sichernden Dateien von Azu bekommen B. Ich befürchte jedoch, dass einige Dateien hinzugefügt Aund dann entfernt werden, Abevor ich sie kopieren kann B.

Wie kann dies am besten verhindert werden? Idealerweise möchte ich, dass mein aktuelles Backup-Skript jedes Mal ausgeführt wird, wenn sich der Inhalt von Aändert.

oadams
quelle

Antworten:

29

Wenn Sie inotify-tools installiert haben, können Sie inotifywaiteine Aktion auslösen, wenn in eine Datei oder ein Verzeichnis geschrieben wird:

#!/bin/sh
dir1=/path/to/A/
while inotifywait -qqre modify "$dir1"; do
    /run/backup/to/B 
done

Wenn der -qqSwitch völlig still ist, -rist er (falls erforderlich) rekursiv und -ein diesem Fall das zu überwachende Ereignis modify. Von man inotifywait:

In
eine überwachte Datei oder eine Datei in einem überwachten Verzeichnis wurde geschrieben.
jasonwryan
quelle
5
incrondkann auch von Interesse sein.
Shawn J. Goff
1
Cool. Würde ich das obige Skript einfach in meinen bashrc einfügen, damit es ausgeführt wird, wenn ich mich anmelde? Gibt es eine andere Möglichkeit, es die ganze Zeit laufen zu lassen?
oadams
Für die Anmeldung, ja /etc/profilefür das gesamte System oder .bash_profilenur für Ihren Benutzer. Die Ausführung nach dem Booten hängt von Ihrer Unix / Linux-Version ab. /etc/rc.local, /etc/rc.d/oder/etc/init.d/
jasonwryan
1
Für größere Verzeichnisse empfiehlt es sich, den --monitorSchalter zu verwenden (und die Ausgabe stattdessen an die Schleife weiterzuleiten), da es sonst zu einem hohen Overhead kommt, wenn inotifywaitimmer wieder gestartet wird
Tobias Kienzler,
Wie zuverlässig würde diese Lösung funktionieren, um ein Skript für jede Datei auszuführen, die in einem Verzeichnisbaum über einen FTP-Server hinzugefügt wurde (nehmen wir an, dass durchschnittlich alle 3 Minuten eine neue Datei hinzugefügt wird, und dies könnte Jahre dauern)? Wenn nicht sehr, gibt es eine alternative Lösung?
Nikola Novak
5

Streng genommen kann es vorkommen, dass jemand eine Datei fallen lässt und sie sehr schnell entfernt. Die Verwendung von inotify (unter Linux oder einer ähnlichen Funktion unter anderen Unices) macht das Risikofenster klein.

Wenn Sie das Dateisystem Ihrer Wahl in dieses Verzeichnis mounten können (ich weiß, dass dies möglicherweise keine Option ist), können Sie ein Verzeichnis einfügen , das alle Dateiversionen aufzeichnet, z. B. copyfs .

Gilles 'SO - hör auf böse zu sein'
quelle
4

Versuchen Sie es mit einem entrBefehlszeilentool, mit dem beliebige Befehle ausgeführt werden können, wenn sich Dateien ändern. Seit Version 2.9 wurde eine Verzeichnisüberwachungsoption ( -d) hinzugefügt, um auf Ereignisse zu reagieren, wenn eine neue Datei zu einem Verzeichnis hinzugefügt wird.

Beispiel zum Ausführen des Dienstprogramms, wenn dem Projekt eine neue Datei hinzugefügt wird:

$ while true; do
> echo src/* | entr -d your_command
> done

Im Verzeichnisüberwachungsmodus wird das übergeordnete Verzeichnis jeder Datei implizit zur Überwachungsliste hinzugefügt.

Dies hat nur zur Folge, dass eine neue Datei beendet werden muss, damit eine externe Shell-Schleife das Dateisystem erneut durchsuchen kann.

Hier ist die Version ohne Verzeichnisüberwachung:

$ while true; do
> echo src/* src | entr your_command
> done

Hier ist ein einfaches Beispiel, das von Ihren Bedürfnissen abhängt:

$ ls -d * | entr sh -c 'rsync -vuar A B'

Check: entrproject.org Website für weitere Informationen.

Kenorb
quelle
3

Das Programm, das Sie suchen, ist inotify.

Kevin
quelle