web-dev-qa-db-fra.com

Comment synchroniser deux dossiers avec des outils de ligne de commande?

Ayant migré vers Linux depuis Windows, j'aimerais trouver un logiciel alternatif à Winmerge ou plutôt apprendre des outils en ligne de commande pour comparer et synchroniser deux dossiers sur Linux. Je vous serais reconnaissant de bien vouloir me dire comment effectuer les tâches suivantes sur la ligne de commande ... (J'ai étudié diff et rsync, mais j'ai encore besoin d'aide.)

Nous avons deux dossiers: "/ home/user/A" et "/ home/user/B"

Le dossier A est l'endroit où les fichiers et dossiers normaux sont enregistrés et le dossier B est un dossier de sauvegarde qui sert de miroir complet du dossier A. (Rien n'est directement enregistré ou modifié par l'utilisateur dans le dossier B.)

Mes questions sont:

  • Comment lister les fichiers qui n'existent que dans le dossier B? (Par exemple, ceux supprimés du dossier A depuis la dernière synchronisation.)

  • Comment copier des fichiers qui n'existent que dans le dossier B dans le dossier A?

  • Comment lister les fichiers qui existent dans les deux dossiers mais qui ont des horodatages ou des tailles différentes? (Ceux qui ont été modifiés dans le dossier A depuis la dernière synchronisation. Je voudrais éviter d'utiliser des sommes de contrôle, car il y a des dizaines de milliers de fichiers et cela rendrait le processus trop lent.)

  • Comment faire une copie exacte du dossier A dans le dossier B? Je veux dire, copiez tout du dossier A dans le dossier B qui n'existe que dans le dossier A et supprimez tout dans le dossier B qui n'existe que dans le dossier B, mais sans toucher aux fichiers qui sont les mêmes dans les deux dossiers.

79
akopacsi

Cela place le dossier A dans le dossier B:

rsync -avu --delete "/home/user/A" "/home/user/B"  

Si vous souhaitez que le contenu des dossiers A et B soit le même, mettez /home/user/A/ (avec la barre oblique) comme source. Cela ne prend pas le dossier A mais tout son contenu et le place dans le dossier B. Comme ceci:

rsync -avu --delete "/home/user/A/" "/home/user/B"
  • -a Faire la synchronisation en préservant tous les attributs du système de fichiers
  • -v exécuter verbalement
  • -u copier uniquement les fichiers avec une heure de modification plus récente (ou différence de taille si les heures sont égales)
  • --delete supprimer les fichiers du dossier cible qui n'existent pas dans la source

Page de manuel: https://download.samba.org/pub/rsync/rsync.html

106
TuxForLife

Vous pourriez unison outil développé par Benjamin Pierce chez U Penn.

Supposons que vous ayez deux répertoires,

/home/user/Documents/dirA/ et /home/user/Documents/dirB/

Pour synchroniser ces deux, vous pouvez utiliser:

~ $ unison -ui text /home/user/Documents/dirA/ /home/user/Documents/dirB/

En sortie, unison affichera chaque répertoire et fichier différent dans les deux répertoires que vous avez demandé de synchroniser. Il recommandera de synchroniser additivement (répliquer le fichier manquant aux deux emplacements) lors de l'exécution initiale, puis de créer et de maintenir une arborescence de synchronisation sur votre machine, et lors des exécutions suivantes, il implémentera une véritable synchronisation (c'est-à-dire si vous supprimez un fichier de .../dirA, il sera supprimé de .../dirB ainsi que. Vous pouvez également comparer chaque changement et éventuellement choisir de avancer ou inverser synchroniser entre les deux répertoires.

Facultativement, pour lancer l'interface graphique, supprimez simplement le -ui text option de votre commande, bien que je trouve le cli plus simple et plus rapide à utiliser.

Plus d'informations à ce sujet: Tutoriel Unison dans la documentation utilisateur Unison .

12
axolotl

C'est ce que j'utilise pour sauvegarder des fichiers personnels, où je ne me soucie pas de tout ce qui est couvert par -a, et souhaite imprimer des informations plus utiles.

rsync -rtu --delete --info=del,name,stats2 "/home/<user>/<src>/" "/run/media/<user>/<drive>/<dst>"

À partir de la page de manuel rsync :

-r, - récursif
Ceci indique à rsync de copier les répertoires de manière récursive.

-t, --times
Ceci indique à rsync de transférer les heures de modification avec les fichiers et de les mettre à jour sur le système distant.

-u, --update
Cela force rsync à ignorer tous les fichiers qui existent sur la destination et dont l'heure modifiée est plus récente que le fichier source. (Si un fichier de destination existant a un temps de modification égal à celui du fichier source, il sera mis à jour si les tailles sont différentes.)

--supprimer
Ceci indique à rsync de supprimer les fichiers superflus du côté réception (ceux qui ne sont pas du côté envoi), mais uniquement pour les répertoires qui sont synchronisés.

--info = DRAPEAUX
Cette option vous permet d'avoir un contrôle précis sur la sortie d'informations que vous souhaitez voir.

De rsync --info=help

DEL        Mention deletions on the receiving side  
NAME       Mention 1) updated file/dir names, 2) unchanged names  
STATS      Mention statistics at end of run (levels 1-3)

Bien que moins explicite, cela est apparemment équivalent et plus court:

rsync -rtuv --delete --info=stats2 "/home/<user>/<src>/" "/run/media/<user>/<drive>/<dst>"

-v, --verbose
Un seul -v vous donnera des informations sur les fichiers qui sont transférés et un bref résumé à la fin [stats1].

1
Honest Abe

La réponse de TuxForLife est plutôt bonne, mais je vous suggère fortement d'utiliser -c lors de la synchronisation locale. Vous pouvez affirmer que cela ne vaut pas la peine de temps/réseau de le faire pour les synchronisations à distance, mais cela en vaut vraiment la peine pour les fichiers locaux car la vitesse est si grande.

-c, --checksum
       This forces the sender to checksum every regular file using a 128-bit  MD4
       checksum.   It  does this during the initial file-system scan as it builds
       the list of all available files. The receiver then checksums  its  version
       of  each  file  (if  it exists and it has the same size as its sender-side
       counterpart) in order to decide which files need to be updated: files with
       either  a  changed  size  or a changed checksum are selected for transfer.
       Since this whole-file checksumming of all files on both sides of the  con-
       nection  occurs  in  addition to the automatic checksum verifications that
       occur during a file's transfer, this option can be quite slow.

       Note that rsync always verifies that each transferred file  was  correctly
       reconstructed  on  the receiving side by checking its whole-file checksum,
       but that automatic after-the-transfer verification has nothing to do  with
       this  option's  before-the-transfer  "Does  this file need to be updated?"
       check.

Cela montre comment avoir la même taille et les mêmes horodatages peut vous échouer.

La mise en place

$ cd /tmp

$ mkdir -p {A,b}/1/2/{3,4}

$ echo "\___________from A" | \
      tee A/1/2/x  | tee A/1/2/3/y  | tee A/1/2/4/z  | \
  tr A b | \
      tee b/1/2/x  | tee b/1/2/3/y  | tee b/1/2/4/z  | \
      tee b/1/2/x0 | tee b/1/2/3/y0 >     b/1/2/4/z0

$ find A b -type f | xargs -I% sh -c "echo %; cat %;"
A/1/2/3/y
\___________from A
A/1/2/4/z
\___________from A
A/1/2/x
\___________from A
b/1/2/3/y
\___________from b
b/1/2/3/y0
\___________from b
b/1/2/4/z
\___________from b
b/1/2/4/z0
\___________from b
b/1/2/x
\___________from b
b/1/2/x0
\___________from b

Le rsync qui ne copie rien car les fichiers ont tous la même taille et le même horodatage

$ rsync -avu A/ b
building file list ... done

sent 138 bytes  received 20 bytes  316.00 bytes/sec
total size is 57  speedup is 0.36

$ find A b -type f | xargs -I% sh -c "echo %; cat %;"
A/1/2/3/y
\___________from A
A/1/2/4/z
\___________from A
A/1/2/x
\___________from A
b/1/2/3/y
\___________from b
b/1/2/3/y0
\___________from b
b/1/2/4/z
\___________from b
b/1/2/4/z0
\___________from b
b/1/2/x
\___________from b
b/1/2/x0
\___________from b    

Le rsync qui fonctionne correctement car il compare les sommes de contrôle

$ rsync -cavu A/ b
building file list ... done
1/2/x
1/2/3/y
1/2/4/z

sent 381 bytes  received 86 bytes  934.00 bytes/sec
total size is 57  speedup is 0.12

$ find A b -type f | xargs -I% sh -c "echo %; cat %;"
A/1/2/3/y
\___________from A
A/1/2/4/z
\___________from A
A/1/2/x
\___________from A
b/1/2/3/y
\___________from A
b/1/2/3/y0
\___________from b
b/1/2/4/z
\___________from A
b/1/2/4/z0
\___________from b
b/1/2/x
\___________from A
b/1/2/x0
\___________from b
1
Bruno Bronosky

Vous pouvez l'utiliser de cette façon:

rsync -avu --delete /home/user/A/* /home/user/B/

De cette façon, vous copiez le contenu du dossier A dans le dossier B, pas le contenu du dossier A lui-même.

0
Isaias Sanchez

Ce n'est pas tout à fait la même chose que ce que vous demandez, mais vous pourriez envisager d'utiliser un outil de contrôle de version. Des outils comme Git font tout ce que vous demandez, et plus encore, surtout si vous ne travaillez pas directement dans le dossier B, il pourrait être intéressant de l'examiner. vous pouvez trouver plus d'informations sur git ici

0
switch87

Vous pourriez jeter un œil à Fitus/Zaloha.sh . Il s'agit d'un synchroniseur implémenté en tant que script shell bash qui utilise uniquement des commandes Unix standard. C'est facile a utiliser:

$ Zaloha.sh --sourceDir="test_source" --backupDir="test_backup"
0
user380458