Acabo de "mover" un directorio de 49 GB a una ruta de archivo incorrecta, ¿es posible restaurar el estado original de los archivos?

58

Tengo (bueno, tenía ) un directorio:

/media/admin/my_data

Tenía aproximadamente 49 GB de tamaño y tenía decenas de miles de archivos. El directorio es el punto de montaje de una partición LUKS activa.

Quería cambiar el nombre del directorio a:

/media/admin/my_data_on_60GB_partition

No me di cuenta en ese momento, pero emití el comando desde el directorio de inicio, así que terminé haciendo:

~% sudo mv /media/admin/my_data my_data_on_60GB_partition

Entonces, el mvprograma comenzó a moverse /media/admin/my_datay su contenido a un nuevo directorio ~/my_data_on_60GB_partition.

Solía Ctrl+ Cpara cancelar el comando a mitad de camino, así que ahora tengo un montón de archivos divididos en directorios:

~/my_data_on_60GB_partition    <---  about 2GB worth files in here

y

/media/admin/my_data           <---- about 47GB of orig files in here    

El nuevo directorio ~/my_data_on_60GB_partitiony algunos de sus subdirectorios son propiedad de root.
Supongo que el mvprograma debe haber copiado los archivos como root inicialmente y luego, después de la transferencia chown, los ha devuelto a mi cuenta de usuario.

Tengo una copia de seguridad algo antigua del directorio / partición.
Mi pregunta es, ¿ es posible restaurar de manera confiable el grupo de archivos que se movieron?

Es decir, ¿puedo simplemente ejecutar:

sudo mv ~/my_data_on_60GB_partition/*  /media/admin/my_data

¿O debería dejar de intentar recuperarme, ya que los archivos están posiblemente dañados y parcialmente completos, etc.?

  • SO - Ubuntu 16.04
mv --version  
mv (GNU coreutils) 8.25
the_velour_fog
fuente
36
Adquiera el hábito cuando entre en pánico para escribir Control-Z(pausar) en lugar de hacerlo Control-C. En este caso, podrá ver qué archivo se estaba transfiriendo en ese momento y saber qué archivo se copió solo parcialmente. Luego puede decidir con calma cómo proceder. (Usar kill -stoppara procesos que no están en el tty).
meuh
1
2GB + 47GB = 60GB ???
tbodt
77
@tbodt (2GB + 47GB) < 60GB. la capacidad de partición es de 60 GB, el tamaño de la carpeta y su contenido: 49 GB.
the_velour_fog

Respuestas:

87

Al mover archivos entre sistemas de archivos, mvno elimina un archivo antes de que termine de copiarlo, y procesa los archivos secuencialmente (inicialmente dije que copia, luego elimina cada archivo a su vez, pero eso no está garantizado; al menos las mvcopias GNU luego eliminan cada comando) argumento de línea a su vez, y POSIX especifica este comportamiento ). Por lo tanto, debe tener como máximo un archivo incompleto en el directorio de destino, y el original seguirá estando en el directorio de origen.

Para mover las cosas hacia atrás, agregue la -ibandera para mvque no sobrescriba nada:

sudo mv -i ~/my_data_on_60GB_partition/* /media/admin/my_data/

(suponiendo que no tiene ningún archivo oculto desde el que restaurar ~/my_data_on_60GB_partition/), o mejor aún (dado que, como descubrió, podría tener muchos archivos esperando ser eliminados), agregue la -nbandera para mvque no sobrescriba nada pero no preguntarte al respecto:

sudo mv -n ~/my_data_on_60GB_partition/* /media/admin/my_data/

También puede agregar la -vbandera para ver qué se está haciendo.

Con cualquier compatible con POSIX mv, la estructura de directorio original aún debe estar intacta, por lo que también puede verificar eso, y simplemente eliminar /media/admin/my_data... (Sin embargo, en el caso general, creo que la mv -nvariante es el enfoque seguro, maneja todas las formas de mv, incluyendo eg mv /media/admin/my_data/* my_data_on_60GB_partition/ .)

Probablemente necesite restaurar algunos permisos; puedes hacerlo en masa usando chowny chmod, o restaurarlos desde copias de seguridad usando getfacly setfacl(gracias a Sato Katsura por el recordatorio ).

Stephen Kitt
fuente
Gracias Stephen Kitt, ¡es una gran ayuda! Puedo usar findpara buscar y establecer permisos. Hay muchos archivos en el nuevo directorio que tienen espacios en los nombres de archivo, pero no hay archivos ocultos, que yo sepa. ¿Crees que el globo en el comando sudo mv -i ~/my_data_on_60GB_partition/* /media/admin/my_data/expandiría el nombre de archivo sin problemas de división de palabras? Estaba pensando alternativamente que podría usar sudo rsync ~/my_data_on_60GB_partition/ /media/admin/my_data/lo que creo que manejaría las rutas de archivos con espacios.
the_velour_fog
66
Solo para estar seguro, cuando suceden cosas como la OP descrita, utilizo rsyncen su lugar, por lo que también verificaría la integridad de todos los archivos. Pero es bueno saber que no necesito eso.
Hauleth
1
@the_velour_fog globbing maneja espacios en nombres de archivos sin problemas.
Stephen Kitt
55
Yo su command mv -i ...(o su /bin/mv -i ...), en lugar de sudo mv -i ...), en caso de que algún administrador (extraño) hiciera "mv" una función que hace "mv -f" en el nivel del sistema (es decir, / etc / profile o tales archivos de todo el sistema) ... Comando algo: inicie el comando algo, y no una función o alias del mismo nombre. (por ejemplo: uno podría ser (¡muy!) desafortunado y tener un (¡muy, muy malo!) function mv { /bin/mv -f -- "$@" }en un archivo que siempre se obtiene, y luego "rm -i something" no preguntará nada (y solo protestará) "-i ! "archivo no existe) ... [he ver tales cosas ... tiritar ]
Olivier Dulac
3
@OlivierDulac: un ejemplo perfecto de por qué es una mala práctica usar alias o scripts con los mismos nombres que los programas estándar.
Joe
19

Después de obtener la respuesta de Stephen Kitt y discutir este comando como una posible solución:

sudo mv -i ~/my_data_on_60GB_partition/* /media/admin/my_data/

Decidí esperar a ejecutarlo hasta que entendí lo que estaba sucediendo, esta respuesta describe lo que descubrí y terminé haciendo.

Estoy usando Gnu mvque copia archivos al destino, luego solo si la operación de copia es exitosa, elimina el original.
Sin embargo, quería confirmar si mvrealiza esta secuencia un archivo a la vez, si eso fuera cierto, el contenido de la carpeta original se habría dividido limpiamente en dos partes, una parte desplazada al destino y la otra aún se queda en la fuente. Y posiblemente habría un archivo que se interrumpió durante la copia, lo que sería común entre los dos directorios, y probablemente tendría un formato incorrecto.

Para descubrir archivos que eran comunes entre los dos directorios, ejecuté:

~% sudo diff -r --report-identical-files my_data_on_60GB_partition/. /media/admin/mydata/. | grep identical | wc -l
14237

Este resultado sugirió que había 14,237 instancias de los mismos archivos en los directorios de origen y de destino, confirmé al verificar los archivos manualmente; sí, había muchos de los mismos archivos en ambos directorios. Esto sugiere que solo después de mvcopiar grandes extensiones de archivos, se realiza la eliminación de los archivos de origen. Una búsqueda rápida en infoel mvcomando mostró

[ mv] Utiliza primero parte del mismo código que utiliza cp -apara copiar los directorios y archivos solicitados, luego (suponiendo que la copia se realizó correctamente) elimina los originales. Si la copia falla, se elimina la parte que se copió a la partición de destino.

No ejecuté el comando pero sospecho que si intenté ejecutar

sudo mv -i ~/my_data_on_60GB_partition/* /media/admin/my_data/

La -i solicitud antes de sobrescribir probablemente se habría activado más de 14,000 veces.

Entonces, para averiguar cuántos archivos totales hay en el directorio recién creado:

~% sudo find my_data_on_60GB_partition/ -type f -a -print | wc -l                                                                    
14238

Entonces, si había un total de 14238 archivos regulares en el nuevo directorio y 14237 tenía originales idénticos en la fuente, eso significa que solo había un archivo en el nuevo directorio que no tenía un archivo idéntico correspondiente en la fuente. Para averiguar cuál era ese archivo, ejecuté rsync en la dirección de la fuente:

~% sudo rsync -av --dry-run my_data_on_60GB_partition/ /media/admin/my_data
sending incremental file list
./
Education_learning_reference/
Education_learning_reference/Business_Education/
Education_learning_reference/Business_Education/Business_education_media_files/
Education_learning_reference/Business_Education/Business_education_media_files/Jeff Hoffman - videos/
Education_learning_reference/Business_Education/Business_education_media_files/Jeff Hoffman - videos/Jeff and David F interview/
Education_learning_reference/Business_Education/Business_education_media_files/Jeff Hoffman - videos/Jeff and David F interview/018 business plans-identifying main KPIs.flv

sent 494,548 bytes  received 1,881 bytes  330,952.67 bytes/sec
total size is 1,900,548,824  speedup is 3,828.44 (DRY RUN)

Una comprobación rápida confirmó que se trataba del archivo con formato incorrecto, donde el archivo existía tanto en el origen como en el destino, archivo de destino = 64 MB, original = 100 MB. Este archivo y su jerarquía de directorios todavía era propiedad de root y aún no se habían restaurado los permisos originales.

Entonces en resumen:

  • todos los archivos que mvnunca llegaron todavía están de vuelta en sus ubicaciones originales (obviamente)
  • todos los archivos que se mvcopiaron completamente todavía tenían sus copias originales en el directorio fuente
  • el archivo que se copió solo parcialmente todavía tenía el original de nuevo en el directorio de origen

En otras palabras, todos los archivos originales todavía estaban intactos y la solución en este caso era simplemente eliminar el nuevo directorio.

the_velour_fog
fuente
Wow ... He actualizado mi respuesta, -nsería mejor en el caso general. Verifiqué el mvcódigo fuente, elimina la fuente un argumento a la vez.
Stephen Kitt
@StephenKitt ah bien. Me preguntaba cuándo mvhace la eliminación en la fuente. Entonces, ¿el comando mv foo bar bazse movería foopara baz/foo luego eliminar el original y fooluego moverse bara baz/bar...?
the_velour_fog
Si, eso es correcto; de hecho, eso es lo que POSIX especifica (básicamente, para que cualquier error que afecte a cualquier argumento fuente deje intacta toda la jerarquía fuente).
Stephen Kitt
Creo que podría haber utilizado diff para encontrar el archivo sin terminar también.
StarWeaver
1
Debería usar en cmplugar de diffcomparar archivos binarios. Además, su discusión anterior tiene sentido solo cuando mueve archivos a través de diferentes sistemas de archivos. No hay copia involucrada al mover archivos dentro del mismo sistema de archivos.
Satō Katsura
4

Solo pensé en comentar que algunas personas pueden tener la tentación de tirar 'xargs' en la mezcla para ejecutar las cosas en paralelo. Eso me da los pelos de punta y realmente me gusta la solución rsync anterior.

En cuanto al material del sistema de archivos sobre mover y copiar y cuando se elimina exactamente el original, el VFS y el sistema de archivos subyacente se coordinan para garantizar la atomicidad por archivo antes de llegar a ese paso de eliminación. Entonces, incluso si se interrumpe antes de que el archivo de destino esté completamente escrito, todo el bloqueo en el VFS es realmente estricto y protege contra cosas como el intercalado de datos aleatorios incluso en casos paralelos. (Trabajé en Linux VFS y NFS4)

Agregar 'xargs' a la mezcla probablemente habría hecho que el paso de verificación de doble cordura fuera un dolor de cabeza, con múltiples archivos en medio del tránsito. Desearía tener más scripting de nivel de sistema. ¡Buenos recordatorios para mí!

Me encantó la pregunta, bueno para telarañas, y me hace amar rsync nuevamente. ¡Salud!

david richter
fuente
1
Sin mencionar el problema cuando los nombres de archivo contienen espacios en blanco.
Comodín