Recuperar archivos borrados con rm -rf en ext4
Si ejecutó rm -rf en la ruta equivocada, deje de escribir en el disco y desmóntelo. Conozca las opciones reales de recuperación en ext4, paso a paso.
Qué hacer durante los primeros sesenta segundos
Hay dos factores que determinan si puede recuperar archivos eliminados con rm -rf. Ambos se producen antes de abrir un buscador. Deje de escribir en ese sistema de archivos. Después, deje de usarlo desmontándolo o volviéndolo a montar en modo de solo lectura.
rm no borra nada. Elimina la entrada del directorio y marca el inode y los bloques de datos del archivo como libres. Los bytes siguen en el dispositivo. Permanecen allí hasta que el asignador de bloques entrega esos bloques a otra cosa y esa otra cosa los sobrescribe. Cada segundo que el sistema de archivos permanece montado y en uso, un daemon escribe una línea en un registro o una base de datos vacía una página. Cualquiera de esas escrituras puede ocupar los bloques que quiere recuperar.
Por tanto, los primeros comandos deben detener las escrituras, no recuperar archivos.
sudo systemctl stop nginx postgresql
sudo umount /mnt/dataSi umount responde umount: /mnt/data: target is busy., busque qué está manteniendo abierto el sistema de archivos.
sudo fuser -vm /mnt/data
sudo lsof +D /mnt/dataSi no puede liberarlo, vuelva a montarlo en modo de solo lectura. Un montaje de solo lectura detiene las nuevas asignaciones, que es lo que necesita en la mayoría de los casos.
sudo mount -o remount,ro /mnt/dataSi la ruta eliminada estaba en el sistema de archivos raíz, el proceso es más difícil. sudo mount -o remount,ro / normalmente fallará con mount: /: cannot remount /dev/vda1 read-only., porque los procesos en ejecución mantienen archivos abiertos para escritura y el kernel no los cerrará de forma forzada. En un VPS, la opción práctica es el modo de rescate o recuperación del proveedor. Este modo arranca un sistema live independiente con el disco conectado, pero sin montarlo. Todos los comandos siguientes se ejecutan entonces sobre un dispositivo en el que ningún proceso escribe.
Hay una regla que se aplica a toda esta guía. Nunca escriba archivos recuperados, una imagen de disco ni una herramienta recién instalada en el sistema de archivos desde el que está recuperando los datos. Conecte un segundo volumen o envíe el resultado a otra máquina mediante SSH.
Por qué la recuperación tras rm -rf en ext4 es casi imposible
Ajuste sus expectativas antes de instalar nada. Confirme con qué sistema de archivos está trabajando:
lsblk -fEn ext4, el sistema de archivos predeterminado en casi todas las imágenes de VPS, la ubicación de los datos de un archivo se almacena en su inode como un árbol de extents. Un extent es un registro que indica que el bloque lógico N de ese archivo comienza en el bloque físico M y ocupa L bloques. Los archivos pequeños almacenan hasta cuatro de esos registros dentro del propio inode. Los archivos grandes apuntan a bloques adicionales que contienen el resto del árbol.
Cuando desaparece el último enlace a un archivo, ext4 recorre ese árbol, devuelve cada extent al asignador de bloques y borra el árbol del inode. Después, el inode se marca como libre y se registra la hora de eliminación. Los datos no se modifican. El único registro de su ubicación se ha borrado.
Esta es la diferencia con ext3, donde un inode eliminado conservaba información suficiente para que una herramienta como ext3grep pudiera seguirlo. En ext4 todavía puede listar los inodes eliminados:
sudo debugfs -R lsdel /dev/vdb1debugfs abre el dispositivo en modo de sólo lectura, salvo que se pase -w, por lo que es seguro usarlo en un dispositivo desmontado y no cuesta nada probarlo. Los inodes aparecerán en la lista. El proceso termina al volcar uno, porque el mapa de bloques que contenía ese inode se ha borrado y dump no tiene nada que seguir.
Dos herramientas intentan sortear esta limitación leyendo el journal. El journal es un anillo de tamaño fijo que ext4 utiliza para mantener la coherencia de los metadatos tras un fallo, y todavía puede contener una copia anterior del inode, de antes de la eliminación. extundelete y ext4magic lo buscan. Compruebe con qué tamaño está trabajando:
sudo dumpe2fs -h /dev/vdb1 | grep -i journalEl journal sólo contiene metadatos y es pequeño, por lo que la actividad normal de escritura lo sobrescribe continuamente. En un servidor en funcionamiento, el intervalo durante el que todavía existe el inode anterior a la eliminación se mide en minutos. Ninguna de las dos herramientas recibe mantenimiento activo y no están disponibles como paquetes en todas las distribuciones. Considere ambas opciones poco probables, ejecútelas contra un dispositivo desmontado o contra una imagen de disco y no se sorprenda si no devuelven nada.
Si lsblk -f informa de xfs, la situación no mejora, porque tampoco existe una herramienta de recuperación compatible para XFS. El orden de las opciones siguientes no cambia.
¿El archivo sigue abierto en un proceso en ejecución?
Esta es la única recuperación de esta página con buenas probabilidades de éxito. Por eso no debe reiniciar el servicio que usaba el archivo.
Un archivo sólo desaparece por completo cuando dos contadores llegan a cero: el número de entradas de directorio que apuntan a su inode y el número de descriptores de archivo abiertos. rm hace que el primer contador llegue a cero. Si un proceso aún mantiene abierto el archivo, el segundo contador no es cero. Por tanto, el inode y sus bloques siguen asignados, y los datos todavía se pueden leer.
Busque archivos abiertos cuyo recuento de enlaces haya llegado a cero:
sudo lsof +L1+L1 significa listar los archivos abiertos cuyo recuento de enlaces sea inferior a 1. Cada coincidencia muestra el proceso, el número del descriptor, un NLINK de 0 y una ruta que termina en (deleted). Tome el PID y el número del descriptor y páselos a /proc:
sudo ls -l /proc/1234/fdUna entrada tiene este aspecto: 3 -> /var/log/app/events.log (deleted). Ese enlace todavía permite acceder a los datos. Cópielos en otro sistema de archivos:
sudo cp /proc/1234/fd/3 /mnt/rescue/events.logUse cp, no mv. Abrir /proc/1234/fd/3 le proporciona un nuevo descriptor sobre el mismo inode, empezando en el desplazamiento cero. Así obtiene el archivo completo, en lugar de sólo la parte posterior a la posición actual del proceso que escribe.
Hay dos límites que conviene conocer. Un árbol de directorios eliminado no se puede recuperar de esta forma, porque sólo se mantienen abiertos los archivos individuales que un proceso tenía abiertos. Además, un archivo de base de datos copiado mientras el motor está escribiendo produce una copia coherente con un bloqueo del sistema. Por tanto, planifique ejecutar la recuperación propia del motor sobre esa copia en lugar de tratarla como un archivo limpio. Las entradas que lsof muestra con mem en lugar de un número de descriptor corresponden a archivos asignados en memoria. No tienen ninguna entrada /proc/<pid>/fd desde la que se puedan copiar.
¿Tiene una snapshot en btrfs, ZFS o LVM?
Si el sistema de archivos admite snapshots, los archivos eliminados ya están dentro de una, sin cambios. Esto sólo sirve si existía una snapshot antes de la eliminación. Nada que cree ahora puede recuperar el estado anterior.
btrfs mantiene las snapshots como subvolúmenes:
sudo btrfs subvolume list /Examine la snapshot y copie las rutas que necesite con cp -a. Es preferible copiar rutas individuales en lugar de revertir un subvolumen completo, porque una reversión también descarta todo lo escrito desde que se tomó la snapshot.
ZFS expone cada snapshot como un directorio de sólo lectura:
zfs list -t snapshot
ls /tank/data/.zfs/snapshot/El directorio .zfs está oculto y no aparece en un ls simple de la raíz del dataset, pero puede acceder a él por nombre. Copie los archivos desde allí. zfs rollback devuelve todo el dataset al estado de la snapshot indicada y destruye todas las snapshots posteriores a ella, así que úselo como último recurso.
Las snapshots de LVM son volúmenes copy-on-write con un tamaño fijo:
sudo lvs
sudo mount -o ro /dev/vg0/data-snap /mnt/snapMóntela en modo de sólo lectura y copie los archivos. Compruebe lvs antes de confiar en ella, porque una snapshot de LVM que llena el espacio asignado queda invalidada por el kernel. Cuando esto ocurre, su contenido se pierde.
Una snapshot no es una copia de seguridad. Se encuentra en el mismo disco o en el mismo pool que el original, por lo que comparte todos los fallos que pueda sufrir el original. Es muy eficaz para deshacer un error cometido hace dos minutos, que es exactamente lo que se necesita aquí.
Recuperación con PhotoRec sobre una imagen, nunca sobre el disco en uso
Si nada de lo anterior se aplica, queda la recuperación por firmas: analizar el dispositivo sin procesar en busca de patrones de bytes que indiquen el inicio de un tipo de archivo conocido y escribir todo lo que aparezca después. Este método sólo lee los datos de los archivos. Los nombres, la estructura de directorios, las marcas de tiempo y la propiedad pertenecen a los metadatos del sistema de archivos. Esos metadatos son los que rm destruyó, por lo que no se pueden recuperar. Obtendrá archivos llamados f0384512.jpg en un directorio de salida numerado y tendrá que clasificarlos manualmente.
Dos reglas determinan si este método puede funcionar.
Primero, cree una imagen del dispositivo antes de acceder a él con cualquier otra herramienta. En Debian y Ubuntu, el paquete es gddrescue y el binario que instala es ddrescue.
sudo apt update && sudo apt install -y gddrescue testdisk
sudo ddrescue -n /dev/vdb1 /mnt/rescue/vdb1.img /mnt/rescue/vdb1.map/mnt/rescue debe estar en otro dispositivo, con al menos tanto espacio libre como capacidad tenga la partición. lsblk -b muestra los tamaños exactos en bytes. El archivo de mapa permite reanudar una copia interrumpida en lugar de empezar de nuevo. Una vez creada la imagen, puede probar más adelante otra herramienta sobre exactamente los mismos bytes. Esto no es posible si la primera herramienta sobrescribe el disco.
Segundo, indique a la herramienta de recuperación que use el archivo de imagen.
sudo photorec /d /mnt/rescue/recup /mnt/rescue/vdb1.imgphotorec abre un menú de texto. Seleccione la partición, después el tipo de sistema de archivos, luego las firmas de archivo que se deben buscar y, por último, el directorio de destino. Reduzca la lista de firmas a los tipos de archivo que realmente haya perdido antes de iniciar el análisis. La lista predeterminada busca todo y puede entregarle decenas de miles de fragmentos para revisar.
testdisk, incluido en el mismo paquete, tiene su propia función de recuperación de archivos eliminados y sólo admite FAT, exFAT, NTFS y ext2. En ext4, eso deja photorec.
Los archivos fragmentados pueden recuperarse dañados. La recuperación por firmas supone que los bloques de un archivo son contiguos. Por tanto, un archivo que el asignador haya dividido por el disco puede reconstruirse de forma incorrecta o no detectarse. Los archivos multimedia suelen recuperarse razonablemente bien porque tienen cabeceras características. Los archivos de texto plano, configuración y código fuente se recuperan mal porque no existe una firma de bytes que marque el inicio de un script de shell.
El espacio sobrante: cómo se eliminó la ruta equivocada
Casi todos los accidentes con rm -rf son problemas del shell. rm recibe una lista de rutas y elimina cada una en orden. Nunca sabe qué pretendía hacer.
El caso clásico es un único espacio:
rm -rf /home/deploy/app /old
rm -rf /home/deploy/app/oldLa primera línea contiene dos argumentos. Elimina la aplicación y después elimina /old. Si /old no existe, rm no muestra nada, porque -f suprime el error de archivo inexistente. El silencio no confirma que la operación sea correcta.
El segundo caso es una variable sin comillas que contiene un espacio:
dir="/srv/my app"
rm -rf $dirEl shell divide el valor en los espacios en blanco, por lo que rm recibe /srv/my y app como dos rutas independientes. Escrito como rm -rf "$dir", es una sola ruta.
El tercer caso es una variable vacía, normalmente porque falló el comando que debía asignarle un valor:
rm -rf "$TARGET"/*Si TARGET no está definida, se expande a rm -rf /*. GNU rm rechaza la forma sin argumentos: rm -rf / muestra rm: it is dangerous to operate recursively on '/' y se detiene. La forma con comodín no tiene esa protección, porque el shell sustituye /* por una lista de rutas reales de nivel superior antes de que se ejecute rm, y / no forma parte de esa lista, por lo que la protección nunca se activa.
Hábitos que evitan el siguiente incidente
- Encierre entre comillas todas las variables que se usen como rutas. Escriba
"$dir"cada vez, también dentro de pruebas y bucles. - Falle si el valor está vacío.
rm -rf "${TARGET:?TARGET is not set}"/*hace que el shell se detenga con su mensaje antes de que comiencermcuandoTARGETno está definida o está vacía. Coloqueset -euo pipefailal principio de cualquier script que elimine archivos. - Añada
--one-file-system. Indica armque omita cualquier directorio situado en un sistema de archivos distinto del argumento que le proporcionó. Así, una eliminación recursiva no puede entrar en un volumen de copias de seguridad montado ni en un bind mount. - No elimine como root. Una cuenta de servicio sólo puede destruir lo que le pertenece. Este es el motivo principal para ejecutar cada servicio con su propio usuario sin privilegios. Si no sabe qué puede alcanzar una cuenta concreta, leer los bits de permisos en un listado de ls permite comprobarlo con un solo comando.
- Muestre la lista antes de actuar sobre ella. En un script, construya las rutas, use
printf '%s\n'sobre ellas, lea la salida y elimínelas en una segunda pasada. - Mantenga a mano un comando de papelera.
sudo apt install trash-clile proporcionatrash-put,trash-list,trash-restoreytrash-empty. Los archivos eliminados se mueven a~/.local/share/Trash, ytrash-empty 30elimina todo lo que tenga más de treinta días.
Crear un alias de rm para trash-put parece el siguiente paso lógico, pero es una trampa. El alias crea un reflejo que falla en el siguiente servidor que no lo tenga, y los alias no se aplican dentro de los scripts, que es donde ocurren los errores más costosos. Escriba trash-put conscientemente.
La única recuperación que funciona siempre
Todo lo anterior es una posibilidad. Una copia de seguridad no lo es.
Dos cosas hacen que una copia de seguridad sea real. Se ejecuta según una programación sin que tenga que recordarlo, y la ha restaurado al menos una vez. Un repositorio del que nadie ha restaurado nunca es una suposición, porque los problemas que pueden dejarlo inutilizable (una ruta incorrecta en la lista de inclusión o una contraseña del repositorio que nadie anotó) sólo aparecen el día que lo necesita.
Con restic, una restauración requiere dos comandos.
restic -r /srv/restic-repo snapshots
restic -r /srv/restic-repo restore latest --target /mnt/rescue --include /srv/appdataRestaure en un directorio vacío en lugar de hacerlo sobre la ruta activa. Así puede comparar ambas ubicaciones antes de mover nada a su sitio. Configurar copias de seguridad de restic en un VPS explica la configuración del repositorio y el temporizador de systemd que las ejecuta.
Con Borg:
borg list /srv/borg-repo
borg extract /srv/borg-repo::daily-2026-08-08 srv/appdataLas rutas dentro de un archivo de Borg se almacenan sin la barra inicial. Por eso srv/appdata coincide y /srv/appdata no coincide con nada. borg extract escribe en el directorio de trabajo actual. Por eso ejecute cd primero en un directorio temporal.
Si todavía no ha elegido entre ambos, la comparación entre restic y Borg explica la deduplicación y los repositorios de sólo anexado, una propiedad que impide que un servidor comprometido elimine su propio historial de copias de seguridad. Cualquiera de las dos herramientas es válida. La respuesta incorrecta es no ejecutar ninguna.
Un servidor nuevo es el momento más económico para configurar esto, antes de que contenga algo que valga la pena perder. Los primeros diez minutos en un VPS nuevo es donde debe realizar ese trabajo, junto con la configuración de SSH y del firewall.
Después, añada una entrada periódica en el calendario: restaure un directorio del repositorio en /tmp cada mes y lea los archivos. Ese hábito vale más que todas las herramientas de esta página.
FAQ
¿Puedo recuperar un archivo borrado en ext4?
Por lo general, no. Cuando desaparece el último enlace a un archivo, ext4 elimina el árbol de extensiones del inode, por lo que no queda nada en el disco que registre dónde estaban los datos. extundelete y ext4magic buscan en el journal de ext4 una copia anterior de ese inode. Esto sólo ayuda si el borrado ocurrió hace unos minutos y el sistema de archivos no ha tenido actividad desde entonces. Ninguno de los dos proyectos recibe mantenimiento activo. Ejecute cualquiera de ellos contra un dispositivo desmontado o una imagen de disco, nunca contra un sistema de archivos montado, y compruebe primero con qué está trabajando mediante sudo dumpe2fs -h /dev/vdb1 | grep -i journal.
Un servicio todavía tiene abierto el archivo borrado. ¿Puedo recuperarlo?
Sí, y este es el mejor caso. Mientras un proceso mantenga abierto el archivo, su inode y sus bloques de datos siguen asignados, por lo que los datos todavía se pueden leer. No reinicie el servicio, porque cerrar el último descriptor completa el borrado. Ejecute sudo lsof +L1 para mostrar los archivos abiertos cuyo recuento de enlaces es 0. Anote el PID y el número del descriptor de archivo. Después, copie el contenido mediante /proc con sudo cp /proc/1234/fd/3 /mnt/rescue/events.log. Escriba la copia en un sistema de archivos diferente. Las entradas que muestran mem en lugar de un número de descriptor están asignadas en memoria y no tienen una ruta /proc/<pid>/fd desde la que se puedan copiar.
¿Por qué debería crear una imagen del disco en lugar de ejecutar la herramienta de recuperación sobre él?
Porque toda herramienta debe escribir su salida en algún lugar, y una escritura en el sistema de archivos que está recuperando puede ocupar los bloques libres que todavía contienen sus datos. Copie primero la partición a otro dispositivo mediante sudo ddrescue -n /dev/vdb1 /mnt/rescue/vdb1.img /mnt/rescue/vdb1.map. Después, indique el archivo de imagen a photorec. La imagen también permite probar más adelante una segunda herramienta con exactamente los mismos bytes. Esto es imposible una vez que algo ha sobrescrito el original.
¿Sigue destruyendo un sistema Linux el comando rm -rf /?
El comando sin modificaciones no lo hace. GNU rm se niega a ejecutarlo e imprime rm: it is dangerous to operate recursively on '/'. Las formas peligrosas son las que llegan por otra vía. rm -rf "$TARGET"/* con TARGET sin definir se expande a rm -rf /*, y el shell entrega a rm una lista de directorios reales de nivel superior. Ninguno de ellos es /, por lo que la protección nunca se activa. Escriba "${TARGET:?TARGET is not set}" en su lugar y el shell se detendrá antes de ejecutar rm.
¿Una instantánea del sistema de archivos es una copia de seguridad?
No. Una instantánea de btrfs o ZFS se encuentra en el mismo pool que los datos que protege, por lo que un disco defectuoso o la destrucción del pool afectan a ambos. Una instantánea de LVM tiene además el problema de su tamaño fijo: cuando se llena, el kernel la invalida y su contenido desaparece. Las instantáneas son excelentes para deshacer un borrado ocurrido hace dos minutos. Para todo lo demás, mantenga un repositorio en hardware independiente.