web-dev-qa-db-fra.com

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

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 a pas big_folder dans le ~/ après avoir déménagé)

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 -r pour recopier les fichiers car des codes côté serveur accèdent à 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'
17
AGamePlayer

Si un répertoire est déplacé dans le même système de fichiers (la même partition), alors tout ce qui est nécessaire est de renommer le chemin de 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.

Lorsque copie 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 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é le répertoire avec succès à partir de ~/big_folder à ~/some_other_folder/big_folder, je reviendrais sur

mv ~/some_other_folder/big_folder ~/big_folder

... après s'être d'abord assuré qu'il n'y avait pas de répertoire appelé ~/big_folder (s'il y en avait, le déplacement mettrait big_folder de some_other_folder dans le ~/big_folder répertoire en tant que sous-dossier).

64
Kusalananda

La réponse actuelle 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 gros fichiers. 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, en revanche, vous le déplacez vers un périphérique externe, il faudra autant de temps pour le déplacer que si vous utilisiez cp à la place. 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.

12
forest