J'ai utilisé le terminal pour copier des fichiers d'un lecteur à un autre.
sudo mv -vi /location/to/drive1/ /location/to/drive2/
Cependant, cela s'est soudainement arrêté, pendant quelques heures, et sans erreur, après la création d'un répertoire.
Ma propre solution à cela est souvent un mélange de hachage et de comparaison, ce qui est surtout un gâchis qui prend du temps car je dois maintenant récupérer à partir d'une copie intermédiaire sans vraiment savoir quels fichiers sont manquants (écrits comme une très longue ligne pour zsh - notez que ce script ne fonctionne pas en bash comme écrit):
source_directory="/path/to/source_directory/";
target_directory="/path/to/target_directory/";
while read hash_and_file; do {
echo "${hash_and_file}" | read hash file;
echo "${file}" | sed "s/^/${source_directory}/g" | read copy_from;
echo "${copy_from}" | sed "s/${source_directory}/${target_directory}/g" | read copy_to;
mv -v "${copy_from}" "${copy_to}" | tee -a log;
rm -v "${copy_from}" | tee -a log; };
done <<<$(
comm -23 <( find ${source_directory} -type f -exec sha256sum "{}" \; |
sed "s: ${source_directory}: :g" | sort;
) <( find ${target_directory} -type f -exec sha256sum "{}" \; |
sed "s: ${target_directory}: :g" | sort; ) )
Ceci est sujet aux erreurs si le nom du répertoire cible ou du répertoire source fait partie du chemin d'accès et supprime les fichiers s'ils n'ont pas été déplacés car ils ont été marqués comme doublons. De plus, il ne source pas le répertoire à la fin.
Existe-t-il une meilleure pratique pour récupérer d'un mv interrompu?
la source
cmp
au lieu de hacher. Il a des dépendances, et les mêmes problèmeswhile read
que ceux mentionnés par Gilles. Il est également lent et verbeux. Mais cela libère de l'espace disque plus tôt que la méthode rsync, car les fichiers sont (re) déplacés de la source pendant son exécution. Il peut servir d'inspiration aux courageux.--delete-during receiver deletes during the transfer
et aussi plusieurs autres alternatives utiles:--delete --delete-before --delete-delay --delete-after --delete-excluded
. Donc, oui, rsync est la meilleure alternative,mv
commande ne fonctionne-t-il pas? Peut-être avec*
ajouté au chemin source si la source d'origine était un répertoire.rsync --delete*
ne soit un désastre ! Il supprimera les élémentsdest
qui ne sont pas actuellement danssrc
, donc tous les fichiers qui ont été déplacés avec succès lors de la tentative précédente seront désormais supprimés! Vous pensiez probablement àrsync --remove-source-files
ce que je suis d'accord serait une bonne alternative. ( more1 , more2 )rsync --delete
va seulement supprimer d' autres fichiers qui ne font pas partie de la source. De [man rsync] () * supprimez les fichiers superflus des répertoires dest *. Comprenez ce que signifie étranger : ne pas être synchronisé. Et oui, rsync fournit également un moyen de supprimer les fichiers source après qu'ils ont été correctement transmis.Réponses:
Oubliez d'essayer de réinventer rsync et utilisez rsync.
Assurez-vous d'utiliser une barre oblique de fin sur la source, sinon elle serait copiée vers
/location/to/drive2/drive1
.Vérifiez que la commande a réussi, puis exécutez
rm -rf /location/to/drive1/
.La commande ci-dessus écrasera tout fichier préexistant de
drive2
. Si vous souhaitez inviter l'utilisateur à ignorer les fichiers qui existaient déjà dansdrive2
, comme avecmv -i
, c'est plus compliqué, car vous devez maintenant distinguer les fichiers qui ont déjà été copiés et les fichiers qui n'en ont pas. Vous pouvez passer l'--ignore-existing
option à rsync pour ignorer les fichiers qui existent déjà sur la destination quel que soit leur contenu. Notez que si l'original amv
été interrompu au milieu de la création d'un fichier, ce fichier restera dans son état semi-copié (alors qu'un nursync -a
terminerait correctement sa copie).Si vous souhaitez reproduire le comportement exact de
mv -i
, y compris l'invite, cela pourrait être fait, mais c'est beaucoup plus compliqué.Notez que votre doublure géante est très fragile. S'il existe des noms de fichiers contenant des barres obliques inverses ou des sauts de ligne, ils peuvent ne pas être copiés correctement ou ils peuvent même inciter votre script à supprimer des fichiers arbitraires. N'utilisez donc pas le code de la question, sauf si vous êtes sûr de pouvoir faire confiance aux noms de fichier pour ne pas contenir de barres obliques inversées ou de nouvelles lignes.
Pour référence future, je recommande de ne jamais l'utiliser
mv
pour les grands mouvements cross-drive, précisément parce qu'il est difficile de contrôler ce qui se passe s'il est interrompu. Utilisez rsync pour effectuer la copie, puis retirez l'original.la source
rsync
fait ce que vous essayez de faire, alorsmv
que non. Aussi: copie entre différentes machines; compression pour le transfert; ignorer les fichiers existants à la destination en fonction de l'égalité basée sur l'horodatage ou le hachage; gestion configurable de la propriété, des autorisations, des liens et des fichiers spéciaux; etc. linux.die.net/man/1/rsyncmv
(ou le gestionnaire de fichiers) car il ne déplace qu'une référence vers le fichier / répertoire. Si je dois effectuer un transfert de données réel, j'utilisersync
si l'une des conditions suivantes est vraie: 1) Je déplace plus de fichiers que je ne peux en vérifier le transfert en un coup d'œil; 2) Je prévois avoir besoin de garder les fichiers synchronisés; 3) Je pense que le transfert pourrait être interrompu. Mon point est, pour le cas d'utilisation que vous présentez dans la question,rsync
est tout simplement l'outil, etmv
oucp
ne sont pas.