Ответ: «Возможно, да, но это зависит от типа файловой системы и времени».
Ни один из этих трех примеров не перезапишет физические блоки данных old_file или существующие_file, за исключением случайного.
mv new_file old_file
, Это отвяжет old_file. Если на old_file есть дополнительные жесткие ссылки, блоки в этих оставшихся ссылках останутся неизменными. В противном случае блоки обычно (в зависимости от типа файловой системы) будут помещены в свободный список. Затем, если mv
требуется копирование (в отличие от простого перемещения записей каталога), новые блоки будут выделены как mv
записи.
Эти вновь распределенные блоки могут быть или не быть теми же, которые были только что освобождены . В файловых системах, таких как UFS , блоки распределяются, если это возможно, из той же группы цилиндров, что и каталог, в котором был создан файл. Так что есть вероятность, что отсоединение файла от каталога и создание файла в этом же каталоге будет использоваться повторно ( и перезаписать) некоторые из тех же блоков, которые были только что освобождены. Вот почему стандартный совет для людей, которые случайно удаляют файл, - не записывать новые данные в файлы в их дереве каталогов (и желательно не во всю файловую систему), пока кто-то не попытается восстановить файл.
cp new_file old_file
будет делать следующее (вы можете использовать strace
для просмотра системных вызовов):
open ("old_file", O_WRONLY | O_TRUNC) = 4
Флаг O_TRUNC приведет к освобождению всех блоков данных, как это mv
делалось выше. И, как указано выше, они, как правило, добавляются в свободный список и могут или не могут быть повторно использованы последующими записями, выполненными cp
командой.
vi existing_file
, Если vi
это на самом деле vim
, :x
команда делает следующее:
unlink ("существующий_файл ~") = -1 ENOENT (нет такого файла или каталога)
переименовать ("существующий_файл", "существующий_файл ~") = 0
open ("существующий_файл", O_WRONLY | O_CREAT | O_TRUNC, 0664) = 3
Так что он даже не удаляет старые данные; данные сохраняются в файле резервной копии.
На FreeBSD, vi
делает open("existing_file",O_WRONLY|O_CREAT|O_TRUNC, 0664)
, который будет иметь ту же семантику, что cp
и выше.
Вы можете восстановить некоторые или все данные без специальных программ; все , что вам нужно , grep
и dd
, а также доступ к исходному устройству.
Для небольших текстовых файлов, единственная grep
команда в ответе @Steven D в вопросе, на который вы ссылаетесь, является самым простым способом:
grep -i -a -B100 -A100 'text in the deleted file' /dev/sda1
Но для больших файлов, которые могут быть в нескольких несмежных блоках, я делаю это:
grep -a -b "text in the deleted file" /dev/sda1
13813610612:this is some text in the deleted file
который даст вам смещение в байтах совпадающей строки. Выполните это с помощью ряда dd
команд, начиная с
dd if=/dev/sda1 count=1 skip=$(expr 13813610612 / 512)
Вы также хотели бы прочитать некоторые блоки до и после этого блока. В UFS файловые блоки обычно имеют размер 8 КБ и обычно распределяются довольно непрерывно, причем блоки одного файла чередуются с блоками 8 КБ из других файлов или свободного места. Длина файла в UFS составляет до 7 фрагментов по 1 КБ, которые могут быть или не быть смежными.
Конечно, в файловых системах, которые сжимают или шифруют данные, восстановление может быть не таким простым.
На самом деле в Unix очень мало утилит, которые перезаписывают блоки данных существующего файла. Тот, который приходит на ум, это dd conv=notrunc
. Другой есть shred
.