Je voudrais copier un ensemble de fichiers du répertoire A dans le répertoire B, avec l’avertissement que si un fichier du répertoire A est identique à un fichier du répertoire B, il ne doit pas être copié (et donc son heure de modification ne doit pas être modifiée). mis à jour). Y at-il un moyen de faire cela avec les outils existants, sans écrire mon propre script pour le faire?
Pour en dire un peu plus sur mon cas d'utilisation: je suis en train de générer automatiquement un groupe de .c
fichiers dans un répertoire temporaire (par une méthode qui doit tous les générer de manière inconditionnelle), et lorsque je les régénère , j'aimerais copier uniquement ceux qui ont changé dans le répertoire source réel, laissant les inchangés inchangés (avec leurs anciens temps de création) afin que make
sachent qu’il n’est pas nécessaire de les recompiler. (Tous les fichiers générés ne sont pas des .c
fichiers, cependant, je dois donc faire des comparaisons binaires plutôt que des comparaisons de texte.)
(Remarque: ceci découle de la question que j'ai posée à l' adresse https://stackoverflow.com/questions/8981552/speeding-up-file-comparions-with-cmp-on-cygwin/8981762#8981762 , où j'essayais. pour accélérer le fichier de script que j'utilisais pour effectuer cette opération, mais il me semble que je devrais vraiment demander s'il existe un meilleur moyen de le faire que d'écrire mon propre script - en particulier depuis tout moyen simple de le faire dans un shell Le script invoquera quelque chose comme cmp
sur chaque paire de fichiers, et le démarrage de tous ces processus prend trop de temps.)
la source
diff -qr dirA dirB
pour voir quels fichiers sont uniquesdirA
etdirB
, respectivement.rsync -avnc
ou le long chemin à parcourirrsync --archive --verbose --dry-run --checksum
.Réponses:
rsync est probablement le meilleur outil pour cela. Il y a beaucoup d'options sur cette commande, lisez donc la page de manuel . Je pense que vous voulez l'option --checksum ou le --ignore-times
la source
-t
option est spécifiée) ou à l'heure de synchronisation. (si-t
n'est pas spécifié).rsync
ne le fait pas. Si je fais ceci :,mkdir src dest; echo a>src/a; rsync -c src/* dest; sleep 5; touch src/a; rsync -c src/* dest
alorsstat dest/a
montre que mtime et ctime ont 5 secondes de plus que ceux desrc/a
.--checksum
option, et bien que linux.die.net/man/1/rsync ne contienne absolument rien qui impliquerait que cela ait une incidence sur le fait que la date de modification soit mise à jour, il en résulte néanmoins que la date de modification de destination est laissée. intacte. (Par contre, l'--ignore-times
option n'a pas cet effet; avec elle la date de modification est toujours mise à jour.) Étant donné que cela semble être entièrement non documenté, puis-je m'appuyer dessus?rsync
le flux de travail est le suivant: 1) vérifiez si le fichier doit être mis à jour; 2) si oui, mettez à jour le fichier. L'--checksum
option indique qu'il ne devrait pas être mis à jour etrsync
ne devrait donc pas passer à l'étape 2).--ignore-times
sans--checksum
serait copier tous les fichiers, et donc mettre à jour l'horodatage, même si les fichiers sont identiques.Vous pouvez utiliser le
-u
commutateur pourcp
aimer ainsi:De la page de manuel:
la source
-u
drapeau fait et comment il fonctionne et comment cela aiderait le PO. Toutefois, dans ce cas particulier, cela n’aiderait pas le PO, car il copierait des fichiers identiques s’ils étaient plus récents et modifierait ainsi leur horodatage, ce que le PO veut précisément éviter.Bien que l’utilisation
rsync --checksum
soit un bon moyen général de «copier s’il est modifié», il existe dans votre cas une solution encore meilleure!Si vous voulez éviter de recompiler inutilement des fichiers, utilisez ccache qui a été construit exactement à cette fin! En fait, non seulement cela évitera les recompilations inutiles de vos fichiers générés automatiquement, mais cela accélérera les choses chaque fois que vous le ferez
make clean
et vous recompilerez à partir de zéro.Ensuite, je suis sûr que vous demanderez: "Est-ce que c'est sans danger?" Eh bien, oui, comme l'indique le site Web:
Et il est facile à utiliser en l'ajoutant simplement comme préfixe dans la
CC=
ligne de votre fichier makefile (ou vous pouvez utiliser des liens symboliques, mais la méthode makefile est probablement meilleure).la source
ccache file.c -o file.o
ou l’équivalent, plusieurs centaines de fois car il existe plusieurs centaines defile.c
fichiers. Quand je faisais cela aveccmp
, plutôt queccache
, cela a pris plusieurs minutes - etcmp
est aussi léger queccache
. Le problème est que, sur Cygwin, le démarrage d’un processus prend un temps non négligeable, même pour un processus complètement trivial.for f in src/*; do /bin/true.exe; done
prend 30 secondes, alors oui. Quoi qu'il en soit, je préfère mon éditeur basé sur Windows et, mis à part ce type de problème de synchronisation, Cygwin fonctionne assez bien avec mon flux de travail en tant qu'emplacement léger pour tester des choses localement si je ne télécharge pas sur les serveurs de build. Il est utile d'avoir mon shell et mon éditeur dans le même système d'exploitation. :)Cela devrait faire ce dont vous avez besoin
Où:
la source
-J
est spécifique à bsd; avec GNU xargs c'est le cas-I
), et ne fonctionne pas correctement si le même ensemble de fichiers n'existe pas déjà aux deux emplacements (sitouch x/boo
Grep me le donne alors)Only in ./x: boo
qui provoque des erreurs dans le pipeline). Utilisez un outil conçu pour le travail, commersync --checksum
.J'aime utiliser l' unisson en faveur de
rsync
car il supporte plusieurs maîtres, ayant déjà configuré mes clés SSH et mon vpn séparément.Donc, dans ma crontab d’un seul hôte, je les laisse se synchroniser toutes les 15 minutes:
Ensuite, je pourrai me développer de part et d’autre et les changements se propageront. En fait, pour les projets importants, jusqu'à 4 serveurs reflètent le même arbre (3 exécutent à l'unisson à partir de cron, en indiquant celui qui ne le fait pas). En fait, les hôtes Linux et Cygwin sont mixtes - sauf qu’il ne faut pas s’attendre à des liens souples dans win32 en dehors de l’environnement cygwin.
Si vous allez dans cette voie, faites le miroir initial du côté vide sans le
-batch
, c'est-à-direBien sûr, il existe une configuration pour ignorer les fichiers de sauvegarde, les archives, etc.:
la source
unison
option qui signifie "ne met pas à jour les dates de fichier modifiées en dernier". Est-ce qu'il y a un? Sinon, c’est une excellente réponse à un problème totalement différent.-times
fait ça pour moi. Unison a aussi un mode de fonctionnement à sec, pense-t-il.times=false
(ou laisser-times
) ferait ça. Je ne sais pas comment j'ai raté cela dans la documentation auparavant. Merci!Bien que
rsync --checksum
la réponse soit correcte, notez que cette option est incompatible avec--times
, et cela--archive
inclut--times
, donc si vous voulezrsync -a --checksum
, vous en avez vraiment besoinrsync -a --no-times --checksum
.la source