Відповідь - "Мабуть, так, але це залежить від типу файлової системи та термінів".
Жоден із цих трьох прикладів не замінить фізичні блоки даних old_file або існуючий_file, за винятком випадковості.
mv new_file old_file
. Це дозволить від’єднати old_file. Якщо є додаткові жорсткі посилання на old_file, блоки залишатимуться незмінними в цих решти посилань. В іншому випадку блоки, як правило, (це залежить від типу файлової системи), будуть розміщені у вільному списку. Тоді, якщо mv
потрібно копіювання (протилежне лише переміщенню записів каталогів), нові блоки будуть виділятися як mv
записи.
Ці щойно виділені блоки можуть бути або не бути тими самими, що були звільнені . У файлових системах, таких як UFS , блоки розподіляються, якщо можливо, із тієї ж групи циліндрів, що і каталог, у якому створено файл. Отже, є ймовірність, що від’єднання файлу з каталогу та створення файлу в тому самому каталозі будуть повторно використані ( і перезаписати) деякі з тих самих блоків, які щойно звільнили. Ось чому стандартна порада для людей, які випадково видаляють файл, - не записувати жодних нових даних у файли у своєму дереві каталогів (а краще не у всю файлову систему), поки хтось не може спробувати відновити файл.
cp new_file old_file
зробить наступне (ви можете використовувати strace
для перегляду системних дзвінків):
відкрити ("old_file", O_WRONLY | O_TRUNC) = 4
Прапор O_TRUNC призведе до звільнення всіх блоків даних, як mv
і раніше. І як зазначено вище, вони, як правило, будуть додані до вільного списку і можуть або не можуть повторно використовуватися наступними записами, виконаними cp
командою.
vi existing_file
. Якщо vi
насправді vim
, то :x
команда виконує наступні дії :
unlink ("існуючий_файл ~") = -1 ENOENT (немає такого файлу чи каталогу)
перейменувати ("існуючий_файл", "існуючий_файл ~") = 0
відкрити ("існуючий_файл", 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
.