Utilisation de rsync pour supprimer uniquement les fichiers superflus

13

Quelle est la meilleure façon de comparer deux structures de répertoires et de supprimer les fichiers et répertoires superflus à l'emplacement cible?

J'ai une petite application de galerie de photos Web que je développe. Les utilisateurs ajoutent et suppriment des images via FTP. Le logiciel de galerie Web que j'ai écrit crée de nouvelles vignettes à la volée, mais il ne traite pas des suppressions. Ce que je voudrais faire, c'est planifier un script de commande / bash pour s'en occuper à des intervalles prédéfinis.

Les images originales sont stockées /home/gallery/images/et organisées en albums, à l'aide de sous-répertoires. Les miniatures sont mises en cache /home/gallery/thumbs/, en utilisant la même structure de répertoires et les mêmes noms de fichiers que le répertoire images.

J'ai essayé d'utiliser les éléments suivants pour y parvenir:

rsync  -r --delete --ignore-existing /home/gallery/images /home/gallery/thumbs

ce qui fonctionnerait bien si toutes les vignettes ont déjà été mises en cache, mais il n'y a aucune garantie que ce serait le cas, lorsque cela se produit, le répertoire du pouce contient des images originales en taille réelle.

Comment puis-je réaliser au mieux ce que j'essaie de faire?

Bryan
la source

Réponses:

8

Je ne pense pas que ce rsyncsoit la meilleure approche pour cela. J'utiliserais un bash one-liner comme celui-ci:

$ cd /home/gallery/thumbs && find . -type f | while read file;do if [ ! -f "../images/$file" ];then echo "$file";fi;done

Si ce one-liner produit la bonne liste de fichiers, vous pouvez ensuite le modifier pour exécuter une rmcommande au lieu d'une echocommande.

Tom Shaw
la source
Merci Tom. Je suppose que pour nettoyer également les répertoires, je devrais l'exécuter une deuxième fois, mais en spécifiant les répertoires dans les commandes au lieu des fichiers, et en remplaçant l'écho par rmdir?
Bryan
@Bryan: Oui, cela semble raisonnable. Vous auriez besoin de changer les drapeaux dans le findet dans le [test ]. Bien sûr, soyez très prudent avec la commande que je vous ai donnée et toutes les modifications, et testez soigneusement avec echo!
Tom Shaw
Merci beaucoup, je vais appliquer de grandes quantités d'écho pendant le test.
Bryan
1
Je viens de penser: vous pouvez également tester avec "ls" pour vous assurer qu'il fonctionne bien avec les espaces blancs. Meilleurs vœux.
Tom Shaw
34

Vous avez --existingaussi besoin de :

rsync -r --delete --existing --ignore-existing /home/gallery/images /home/gallery/thumbs

Depuis la page de manuel:

  --existing, --ignore-non-existing
          This tells rsync to skip creating files (including  directories)
          that  do  not  exist  yet on the destination.  If this option is
          combined with the --ignore-existing option,  no  files  will  be
          updated  (which  can  be  useful if all you want to do is delete
          extraneous files).
Joril
la source
1
S'il y a des erreurs, votre réponse géniale ne fonctionnera pas. C'est pourquoi vous devez également ajouter l' --ignore-errorsargument également. C'est la seule chose qui a fonctionné pour moi. Merci pour --existinget --ignore-existing! J'ai utilisé votre réponse comme base de ma réponse ici .
LonnieBest
1
@LonnieBest S'il y a des erreurs, même pas rm, cpou mvfonctionnera comme c'est le cas: ce sont des problèmes qui doivent être examinés et qui empêchent la réussite des opérations. Vous pouvez demander à la plupart des outils d'ignorer les erreurs (par exemple -fpour rm), mais je ne vois pas en quoi cela est pertinent pour la question ou cette réponse.
Mecki