Comment exécuter une commande lorsque le contenu d'un répertoire est mis à jour?

27

Il existe un répertoire Adont le contenu est fréquemment modifié par d'autres personnes.

J'ai créé un répertoire personnel Boù je conserve tous les fichiers qui se sont déjà trouvés A.

À l' heure actuelle, je viens de temps en temps courir rsyncpour obtenir les fichiers à sauvegarder à partir Ade B. Cependant, je crains la possibilité que certains fichiers soient ajoutés A, puis supprimés Aavant d'avoir la possibilité de les copier B.

Quelle est la meilleure façon d'empêcher que cela se produise? Idéalement, j'aimerais que mon script de sauvegarde actuel soit exécuté à chaque fois que le contenu de Aest modifié.

oadams
la source

Réponses:

29

Si vous avez installé inotify-tools, vous pouvez utiliser inotifywaitpour déclencher une action si un fichier ou un répertoire est écrit dans:

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

Lorsque le -qqcommutateur est complètement silencieux, -rest récursif (si nécessaire) et -eest l'événement à surveiller, dans ce cas modify. De man inotifywait:

modifier
Un fichier surveillé ou un fichier d'un répertoire surveillé a été écrit.
jasonwryan
la source
5
incrondpeut également présenter un intérêt.
Shawn J. Goff
1
Cool. Vais-je simplement mettre le script ci-dessus dans mon bashrc afin qu'il s'exécute lorsque je me connecte? Existe-t-il un autre moyen de le faire fonctionner tout le temps?
oadams
Pour la connexion, oui /etc/profilepour l'ensemble du système ou .bash_profileuniquement pour votre utilisateur. Pour l'exécuter après le démarrage, cela dépend de votre version d'Unix / Linux; /etc/rc.local, /etc/rc.d/ou/etc/init.d/
jasonwryan
1
Pour les répertoires plus volumineux, vous voudrez peut-être envisager d'utiliser le --monitorcommutateur (et de diriger la sortie vers votre boucle à la place), sinon il y a beaucoup de surcharge quand il inotifywaitest redémarré maintes et maintes fois
Tobias Kienzler
Dans quelle mesure cette solution fonctionnerait-elle de manière fiable pour exécuter un script pour chaque fichier ajouté dans une arborescence de répertoires via un serveur FTP (disons qu'un nouveau fichier est ajouté toutes les 3 minutes en moyenne et cela peut durer des années)? Sinon, existe-t-il une solution alternative?
Nikola Novak
5

À strictement parler, si quelqu'un dépose un fichier et le supprime très rapidement, vous risquez de le manquer. L'utilisation d' inotify (sous Linux, ou une fonctionnalité similaire sous d'autres unités) réduit la fenêtre de risque.

Si vous pouvez monter le système de fichiers de votre choix sur ce répertoire (je réalise que ce n'est peut-être pas une option), vous pouvez en mettre un qui enregistre toutes les versions de fichiers, par exemple copyfs .

Gilles 'SO- arrête d'être méchant'
la source
4

Essayez l' entroutil de ligne de commande qui peut exécuter des commandes arbitraires lorsque les fichiers changent. Depuis la version 2.9, une option de surveillance de répertoire ( -d) a été ajoutée pour réagir aux événements lorsqu'un nouveau fichier est ajouté à un répertoire.

Exemple pour exécuter l'utilitaire si un nouveau fichier est ajouté au projet:

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

En mode de surveillance de répertoire, le répertoire parent de chaque fichier est implicitement ajouté à la liste de surveillance.

La seule implication de ceci est que si un nouveau fichier apparaît, il doit quitter pour permettre à une boucle de shell externe de réanalyser le système de fichiers.

Voici la version sans option de surveillance de répertoire:

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

Voici un exemple plus simple selon vos besoins:

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

Consultez le site Web entrproject.org pour plus de détails.

kenorb
la source
3

Le programme que vous recherchez est inotify.

Kevin
la source