La respuesta es "Probablemente sí, pero depende del tipo de sistema de archivos y el momento".
Ninguno de esos tres ejemplos sobrescribirá los bloques de datos físicos del archivo antiguo o el archivo existente, excepto por casualidad.
mv new_file old_file
. Esto desvinculará old_file. Si hay enlaces duros adicionales a old_file, los bloques permanecerán sin cambios en los enlaces restantes. De lo contrario, los bloques generalmente (depende del tipo de sistema de archivos) se colocarán en una lista libre. Luego, si se mv
requiere copiar (en lugar de solo mover las entradas del directorio), los nuevos bloques se asignarán como mv
escrituras.
Estos bloques recién asignados pueden o no ser los mismos que fueron liberados . En sistemas de archivos como UFS , los bloques se asignan, si es posible, desde el mismo grupo de cilindros que el directorio en el que se creó el archivo. Por lo tanto, existe la posibilidad de que desvincular un archivo de un directorio y crear un archivo en ese mismo directorio se reutilice ( y sobrescribir) algunos de los mismos bloques que acaban de liberarse. Es por eso que el consejo estándar para las personas que eliminan accidentalmente un archivo es que no escriban datos nuevos en los archivos de su árbol de directorios (y preferiblemente no en todo el sistema de archivos) hasta que alguien pueda intentar la recuperación del archivo.
cp new_file old_file
hará lo siguiente (puede usar strace
para ver las llamadas al sistema):
abierto ("archivo_viejo", O_WRONLY | O_TRUNC) = 4
El indicador O_TRUNC hará que se liberen todos los bloques de datos, tal como se mv
hizo anteriormente. Y como se indicó anteriormente, generalmente se agregarán a una lista gratuita, y pueden o no ser reutilizados por las escrituras posteriores realizadas por el cp
comando.
vi existing_file
. Si vi
es realmente vim
, el :x
comando hace lo siguiente:
unlink ("existente_file ~") = -1 ENOENT (No existe tal archivo o directorio)
renombrar ("archivo_existente", "archivo_existente ~") = 0
abierto ("existente_archivo", O_WRONLY | O_CREAT | O_TRUNC, 0664) = 3
Por lo tanto, ni siquiera elimina los datos antiguos; Los datos se conservan en un archivo de copia de seguridad.
En FreeBSD, vi
does open("existing_file",O_WRONLY|O_CREAT|O_TRUNC, 0664)
, que tendrá la misma semántica que la cp
anterior.
Puede recuperar algunos o todos los datos sin programas especiales; todo lo que necesita es grep
y dd
, y acceso al dispositivo sin formato.
Para archivos de texto pequeños, el grep
comando único en la respuesta de @Steven D en la pregunta a la que se vinculó es la forma más fácil:
grep -i -a -B100 -A100 'text in the deleted file' /dev/sda1
Pero para archivos más grandes que pueden estar en múltiples bloques no contiguos, hago esto:
grep -a -b "text in the deleted file" /dev/sda1
13813610612:this is some text in the deleted file
que le dará el desplazamiento en bytes de la línea correspondiente. Siga esto con una serie de dd
comandos, comenzando con
dd if=/dev/sda1 count=1 skip=$(expr 13813610612 / 512)
También querrás leer algunos bloques antes y después de ese bloque. En UFS, los bloques de archivos generalmente son de 8 KB y generalmente se asignan de manera bastante contigua, los bloques de un solo archivo se intercalan alternativamente con bloques de 8 KB de otros archivos o espacio libre. La cola de un archivo en UFS tiene hasta 7 fragmentos de 1 KB, que pueden ser contiguos o no.
Por supuesto, en los sistemas de archivos que comprimen o encriptan datos, la recuperación podría no ser tan sencilla.
En realidad, hay muy pocas utilidades en Unix que sobrescriban los bloques de datos de un archivo existente. Uno que viene a la mente es dd conv=notrunc
. Otro es shred
.