Pourquoi mv est-il tellement plus rapide que cp? Comment récupérer d'une commande mv incorrecte?

17

Je fais glisser et déposer un dossier dans un autre par erreur dans FileZilla.

~/big_folder
~/some_other_folder

Le dossier a été déplacé est très énorme. Il comprend des centaines de milliers de fichiers (node_modules, petits fichiers image, beaucoup de dossiers)

Ce qui est si bizarre, c'est qu'après avoir relâché ma souris, le déplacement est terminé. Le dossier "big_folder" est déplacé dans "some_other_folder".

~/some_other_folder/big_folder

(il n'y big_folderen a pas ~/après le déménagement)

Ensuite, je réalise l'erreur et j'essaie de reculer, mais cela échoue à la fois sur FileZilla et sur le terminal.

Ensuite, je dois cp -rrecopier les fichiers car il y a des codes côté serveur accédant à ces fichiers dans~/big_folder

Et il faut attendre une éternité ...

Que devrais-je faire?

BTW, voici la sortie de FileZilla (c'est l'échec du recul):

Status:       Renaming '/root/big_folder' to '/root/some_other_folder/big_folder'
Status:       /root/big_folder -> /root/some_other_folder/big_folder

Status:       Renaming '/root/some_other_folder/big_folder' to '/root/big_folder'
Command:  mv "big_folder" "/root/big_folder"
Error:          mv /root/some_other_folder/big_folder /root/big_folder: received failure with description 'Failure'
AGamePlayer
la source
37
Ah, le plus utile des messages d'erreur, received failure with description 'Failure'.
Captain Man
3
Accédez à un terminal et tapez la commande mv /root/some_other_folder/big_folder /root/big_folder. Quel message d'erreur obtenez-vous?
ctrl-alt-delor
J'irais probablement aveccp -al
Nemo
1
La mv vs cpquestion de OP est abordée, mais j'aimerais savoir pourquoi il a pu déplacer le dossier dans un sens instantanément mais pas dans l'autre.
user1717828
4
Pour essentiellement la même raison qu'il est beaucoup plus rapide de déplacer un livre d'une pièce à une autre que de créer une copie du livre.
David Richerby

Réponses:

63

Si un répertoire est déplacé dans le même système de fichiers (la même partition), il suffit alors de renommer le chemin d'accès au fichier du répertoire. Aucune donnée en dehors de l'entrée de répertoire pour le répertoire lui-même ne doit être modifiée.

Lors de la copie de répertoires, les données de chaque fichier doivent être dupliquées. Cela implique de lire toutes les données source et de les écrire à destination.

Déplacer un répertoire entre des systèmes de fichiers impliquerait de copier les données vers la destination et de les supprimer de la source. Cela prendrait aussi longtemps que la copie (duplication) des données dans un seul système de fichiers.


Si FileZilla a renommé avec succès le répertoire de ~/big_folderà ~/some_other_folder/big_folder, je reviendrais sur

mv ~/some_other_folder/big_folder ~/big_folder

... après s'être assuré qu'il n'y avait pas de répertoire appelé ~/big_folder(s'il y avait, le mouvement serait mis big_folderde some_other_folderdans le ~/big_folderrépertoire comme un sous - dossier).

Kusalananda
la source
6
Oh ... est-ce pour cela que je vois le mot "renommer" plutôt que "bouger" dans la sortie?
AGamePlayer
2
@AGamePlayer Oui, correct.
Kusalananda
4
@AGamePlayer "Failure" n'est malheureusement pas une bonne description d'erreur. J'aurais utilisé mv ~/some_other_folder/big_folder ~/après m'être assuré qu'il n'y en avait pas d'autre big_folderdans le répertoire personnel. Je n'ai jamais utilisé FileZilla.
Kusalananda
10
Une autre raison de ne pas dépendre des outils de l'interface graphique Windows pour effectuer la maintenance des fichiers sous Unix.
Mark Stewart
4
@MarkStewart pourquoi "sur Unix" à la fin de votre commentaire ?; Y a-t-il un moment où c'est une bonne idée?
ctrl-alt-delor
11

La réponse existante est excellente, mais je voudrais développer un peu en montrant exactement ce qui se passe lorsque vous vous déplacez par rapport à la copie d'un fichier. Lorsque vous regardez les appels système lors d'une copie, vous voyez:

open("hello1.txt", O_RDONLY)               = 3
open("hello2.txt", O_WRONLY|O_CREAT, 0644) = 4
read(3, "Hello, world!\n", 4096)           = 14
write(4, "Hello, world!\n", 14)            = 14
close(3)                                   = 0
close(4)                                   = 0

Cela ouvre le fichier source, puis crée un deuxième fichier. Il lit ensuite le contenu du fichier source dans la mémoire et écrit cette mémoire dans le fichier de destination. Cela nécessite plusieurs changements de contexte et des E / S disque qui peuvent être assez élevées pour les fichiers volumineux. Cependant, si vous déplacez un fichier, vous voyez:

rename("hello1.txt", "hello2.txt")         = 0

Il est important de se rappeler que le fichier ne sera renommé que s'il se trouve sur la même partition sur le même disque physique. Si vous créez un énorme fichier de plusieurs gigaoctets, puis le déplacez entre deux emplacements dans votre maison, vous remarquerez que l'action se termine instantanément. Si, d'autre part, vous le déplacez vers un périphérique externe, il faudra autant de temps pour le déplacer que si vous l'utilisiez à la cpplace. En effet, le déplacement d'un fichier ne peut se faire qu'en le renommant s'il se trouve sur la même partition.

forêt
la source
L'OP a déplacé un répertoire, pas un fichier.
AL
Cela s'applique toujours, sauf si OP déplace des dossiers vides, ce qui serait le seul cas où aucun fichier n'est impliqué
glace
@AL Dans les systèmes de type Unix, tout est un fichier.
Thegs
@AL Un fichier texte n'est qu'un exemple. Pour un répertoire, la seule différence est que vous en auriez getdents()et que les mkdir()appels seraient dispersés.
forêt