¿Por qué mv es mucho más rápido que cp? ¿Cómo me recupero de un comando mv incorrecto?

17

Arrastro y suelto una carpeta en otra por error en FileZilla.

~/big_folder
~/some_other_folder

La carpeta que se movió es muy grande. Incluye cientos de miles de archivos (node_modules, pequeños archivos de imagen, muchas carpetas)

Lo que es tan extraño es que después de soltar mi mouse, el movimiento está listo. La carpeta "big_folder" se mueve a "some_other_folder".

~/some_other_folder/big_folder

(no hay big_folderen el ~/después de mudarse)

Luego me doy cuenta del error e intento retroceder, pero falla tanto en FileZilla como en la terminal.

Luego tengo cp -rque copiar los archivos nuevamente porque hay códigos del lado del servidor que acceden a esos archivos en~/big_folder

Y lleva como siempre esperar ...

¿Qué tengo que hacer?

Por cierto, aquí están los resultados de FileZilla (es la falla del retroceso):

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
fuente
37
Ah, el más útil de los mensajes de error, received failure with description 'Failure'.
Capitán Man
3
Vaya a una terminal y escriba el comando mv /root/some_other_folder/big_folder /root/big_folder. ¿Qué mensaje de error recibes?
ctrl-alt-delor
Probablemente iría concp -al
Nemo
1
mv vs cpSe aborda la pregunta de OP , pero me encantaría saber por qué pudo mover la carpeta en una dirección al instante, pero no en la otra.
user1717828
44
Esencialmente por la misma razón por la que es mucho más rápido mover un libro de una habitación a otra que crear una copia del libro.
David Richerby

Respuestas:

63

Si un directorio se mueve dentro del mismo sistema de archivos (la misma partición), todo lo que se necesita es cambiar el nombre de la ruta del archivo del directorio. No hay datos aparte de la entrada del directorio para el directorio en sí tiene que ser alterado.

Al copiar directorios, los datos para cada archivo deben duplicarse. Esto implica leer todos los datos de origen y escribirlos en el destino.

Mover un directorio entre sistemas de archivos implicaría copiar los datos al destino y eliminarlos de la fuente. Esto tomaría casi tanto tiempo como copiar (duplicar) los datos dentro de un solo sistema de archivos.


Si FileZilla renombró exitosamente el directorio de ~/big_foldera ~/some_other_folder/big_folder, entonces lo revertiría usando

mv ~/some_other_folder/big_folder ~/big_folder

... después de asegurarse de que no había un directorio llamado ~/big_folder(si lo hubiera, el movimiento se colocaría big_folderdesde some_other_folderel ~/big_folderdirectorio como una subcarpeta).

Kusalananda
fuente
66
Oh ... ¿es por eso que veo la palabra "renombrar" en lugar de "mover" en la salida?
AGamePlayer
2
@AGamePlayer Sí, correcto.
Kusalananda
44
@AGamePlayer "Failure" lamentablemente no es una buena descripción del error. Lo habría usado mv ~/some_other_folder/big_folder ~/después de asegurarme de que no haya otro big_folderen el directorio de inicio. Nunca he usado FileZilla.
Kusalananda
10
Otra razón para no depender de las herramientas de la GUI de Windows para realizar algún mantenimiento de archivos en Unix.
Mark Stewart
44
@ MarkStewart ¿por qué "en Unix" al final de tu comentario ?; ¿Hay algún momento en que sea una buena idea?
ctrl-alt-delor
11

La respuesta existente es excelente, pero me gustaría ampliarla un poco mostrando exactamente lo que sucede cuando te mueves o cuando copias un archivo. Cuando observa las llamadas al sistema durante una copia, ve:

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

Esto abre el archivo fuente, luego crea un segundo archivo. Luego lee el contenido del archivo de origen en la memoria y escribe esa memoria en el archivo de destino. Esto requiere varios cambios de contexto y algunas E / S de disco que pueden ser bastante altas para archivos grandes. Sin embargo, si mueve un archivo, verá:

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

Es importante recordar que solo verá el nombre del archivo si está en la misma partición en el mismo disco físico. Si crea un archivo enorme de varios gigabytes y luego lo mueve entre dos ubicaciones en su hogar, notará que la acción se completa al instante. Si, por otro lado, lo mueve a un dispositivo externo, tardará tanto tiempo en moverse como si lo usara en su cplugar. Esto se debe a que mover un archivo solo se puede hacer cambiando el nombre si está en la misma partición.

bosque
fuente
El OP movió un directorio, no un archivo.
AL
Todavía se aplica aunque, a menos que OP esté moviendo carpetas vacías, que sería el único caso en el que no hay archivos involucrados
glace
@AL En sistemas tipo Unix, todo es un archivo.
Thegs
@AL Un archivo de texto fue solo un ejemplo. Para un directorio, la única diferencia es que tendrías algunos getdents()y mkdir()llamadas dispersas.
bosque