Команда rm -rf без подтверждения - один из тех моментов, когда время вдруг начинает идти очень медленно. Палец отпустил Enter, на экране ничего не произошло, и где-то в подсознании уже зародилась холодная мысль: только что улетело то, что нужно было сохранить. Linux в этом плане намного жёстче Windows и macOS - корзины нет, отката нет, файл исчезает мгновенно. Дальше начинается гонка со временем и фоновыми процессами системы, в которой шансы оценить заранее почти невозможно, но процедуру восстановления стоит знать наизусть. Потому что чем раньше начать действовать правильно, тем выше вероятность, что файл вернётся.

Что физически происходит с файлом, когда вы запускаете rm на ext4

Понимание механизма удаления критично для оценки шансов на восстановление. Когда система выполняет rm, она не стирает данные на диске. Действий три. Запись о файле в каталоге помечается как удалённая. В таблице инодов поле, указывающее на блоки данных, обнуляется. Сами блоки в битмапе свободного пространства помечаются как доступные для записи. Содержимое файла при этом физически остаётся на диске нетронутым - до тех пор, пока на эти блоки не запишется что-то новое.

Главная проблема ext4 в контексте восстановления именно в обнулении указателей на блоки. На старой ext3 указатели в иноде после удаления сохранялись, и инструменты вроде debugfs могли просто перейти по ним и забрать данные. В ext4 указатели затираются ради безопасности на случай аварийного отключения - чтобы файловая система не могла случайно сослаться на освобождённые блоки. Это сильно усложнило задачу восстановления и сделало журнал файловой системы основным источником информации.

Журнал ext4 хранит копии метаданных, включая старые версии инодов с целыми указателями. Если повезло и журнал ещё содержит запись об удалённом файле, восстановление возможно. Если журнал успел перезаписаться, остаётся только сигнатурный поиск по сырым блокам - то, что называется file carving. И вот здесь начинается главное отличие между двумя главными инструментами в арсенале: extundelete работает с метаданными и журналом, photorec (часть пакета testdisk) ищет файлы по сигнатурам внутри сырых данных.

Первые шестьдесят секунд после удаления решают всё

Самое опасное, что можно сделать после случайного удаления - продолжить работать с разделом как ни в чём не бывало. Любой фоновый процесс, любая запись в лог, любой скачанный временный файл может попасть на тот блок, где лежал удалённый файл. И тогда восстановление превратится из задачи на полчаса в дорогую лотерею.

Первое действие - монтирование раздела в режиме только для чтения. Если файл удалён в домашней папке и раздел не корневой, его можно сразу отмонтировать или перемонтировать:

# Перемонтирование в режиме только для чтения
sudo mount -o remount,ro /home

# Если это не получается из-за открытых файлов
sudo umount /home

# Просмотр процессов, держащих раздел
sudo lsof | grep /home
sudo fuser -m /home

Если процессы держат раздел открытым, их нужно остановить или, в крайнем случае, использовать ленивое отмонтирование командой sudo umount -l /home. Ленивое отмонтирование делает раздел недоступным для новых операций, но не убивает существующие - что в большинстве случаев и нужно.

Сложнее всего ситуация, когда удалённый файл лежал на корневом разделе. Перемонтировать его в read-only на работающей системе обычно невозможно - слишком много процессов пишут в /var, /tmp, /etc. Здесь единственный надёжный путь - выключить машину прямо сейчас, не дожидаясь штатной остановки, и загрузиться с Live USB или Live CD. Жёсткое выключение через кнопку питания звучит грубо, но в этом сценарии это правильное решение. Каждая секунда работы системы уменьшает шансы.

Существует и тонкий специальный случай. Если удалённый файл всё ещё открыт каким-то процессом - например, плеер играл музыку, а вы случайно удалили mp3, - файл можно достать прямо из /proc, потому что ядро держит данные в памяти, пока процесс не закроет дескриптор:

# Поиск открытых дескрипторов для удалённого файла
sudo lsof | grep deleted | grep "название_файла"

# В выводе будет видно PID процесса и номер дескриптора
# Копируем файл из procfs
sudo cp /proc/PID/fd/НОМЕР_FD /tmp/recovered.file

Этот приём - самый надёжный способ восстановления, но работает только пока процесс жив и держит файл открытым. Закрытие процесса означает потерю последнего шанса вернуть файл из памяти.

Восстановление через extundelete как первая линия обороны на ext4

Extundelete - специализированный инструмент именно для ext3 и ext4, основанный на анализе журнала файловой системы. Он умеет восстанавливать не только содержимое файла, но и его оригинальное имя, если соответствующая запись в каталоге ещё не перезаписана. Работает только с размонтированным разделом или его побитовой копией.

Установка из репозитория стандартная:

# Debian/Ubuntu
sudo apt install extundelete

# Fedora/RHEL
sudo dnf install extundelete

# Arch
sudo pacman -S extundelete

Прежде чем запускать extundelete на реальном разделе, опытные восстановители сначала делают побитовый образ диска. Это страховка на случай, если в процессе восстановления что-то пойдёт не так. Образ занимает столько же места, сколько и сам раздел, поэтому нужен внешний накопитель достаточного размера:

# Создание побитового образа на внешний диск
sudo dd if=/dev/sda5 of=/mnt/external/recovery.img bs=4M status=progress

# Альтернатива с пропуском повреждённых секторов и подробным логом
sudo ddrescue /dev/sda5 /mnt/external/recovery.img /mnt/external/rescue.log

После того как образ готов, дальнейшую работу можно вести с ним вместо живого раздела. Это позволяет экспериментировать, не боясь окончательно потерять данные. Все команды ниже одинаково работают и с устройством /dev/sda5, и с файлом-образом.

Базовый сценарий восстановления всех удалённых файлов выглядит так. Сначала создаётся отдельная папка на другом разделе, в которой extundelete сложит результаты. Затем инструмент запускается с указанием раздела и целевой папки:

# Создание папки на другом диске для результатов
mkdir -p /mnt/recovery/restored
cd /mnt/recovery/restored

# Восстановление всех удалённых файлов
sudo extundelete /dev/sda5 --restore-all

После завершения работы в текущей рабочей директории появится папка RECOVERED_FILES с содержимым. Часть файлов получит оригинальные имена, часть - имена вида file.NNNNN по номеру инода. Если известно конкретное имя или путь к файлу, можно запросить точечное восстановление:

# Восстановление конкретного файла по пути
sudo extundelete /dev/sda5 --restore-file home/user/Documents/report.pdf

# Восстановление целой папки рекурсивно
sudo extundelete /dev/sda5 --restore-directory home/user/Documents

# Восстановление файлов, удалённых после конкретного момента
sudo extundelete /dev/sda5 --restore-all --after $(date -d "-2 hours" +%s)

Параметр --after принимает unix timestamp и фильтрует только те файлы, которые были удалены позже указанного момента. Это резко уменьшает количество мусора в выводе и ускоряет работу на больших разделах.

Реальность работы с extundelete такова, что на свежем удалении и быстро отмонтированном разделе процент успешного восстановления может достигать 80-90 процентов, особенно для текстовых файлов и небольших документов. На разделе, который продолжал использоваться часы или сутки после удаления, цифры падают до 10-20 процентов и ниже. Если в выводе видно сообщение 0 recoverable inodes found при том, что файлы точно были - значит, журнал не сохранил нужную информацию, и нужно переходить к photorec.

PhotoRec и сигнатурный поиск, когда метаданные уже не помогают

PhotoRec работает принципиально иначе. Он игнорирует структуру файловой системы и сканирует диск побайтово в поисках известных сигнатур начала файлов. У JPEG это последовательность байтов FF D8 FF, у PDF - %PDF, у ZIP - PK\x03\x04. Найдя сигнатуру, программа пытается вычислить размер файла по внутренним заголовкам и сохранить нужный диапазон блоков в новый файл на другом носителе.

Преимущество подхода в том, что photorec работает с любой файловой системой, в том числе с полностью разрушенной. Недостатки прямо вытекают из той же логики. Оригинальные имена файлов не восстанавливаются - photorec не знает, как файл назывался в каталоге. Структура папок теряется полностью. Фрагментированные файлы восстанавливаются плохо, потому что куски разбросаны по диску, и сигнатурный поиск ловит только непрерывные блоки. И главное - photorec вытаскивает абсолютно все файлы, которые когда-либо были на разделе, даже те, что были удалены полгода назад.

Установка и базовый запуск:

# Установка пакета (содержит и testdisk, и photorec)
sudo apt install testdisk

# Запуск photorec с указанием устройства
sudo photorec /dev/sda5

# Альтернатива - работа с образом, который сделали через dd
sudo photorec /mnt/external/recovery.img

После запуска photorec открывает интерактивный текстовый интерфейс. Навигация стрелками, выбор через Enter, выход через q. Базовый сценарий проходит так: выбор устройства, выбор раздела на устройстве, выбор типа файловой системы (для ext4 - ext2/ext3), выбор режима (только свободное место или весь раздел), выбор папки назначения. Важнейший момент - папка назначения обязательно должна находиться на другом физическом носителе. Запись восстановленных файлов на тот же раздел гарантированно затрёт неравномерно поднимаемые данные.

Перед запуском поиска есть смысл зайти в меню File Opt и выключить все типы файлов, кроме нужных. По умолчанию photorec ищет около 480 разных форматов одновременно, и итоговый дамп будет содержать гигабайты мусора - кешированные превью браузеров, фрагменты системных файлов, миниатюры из приложений. Если задача - найти конкретный PDF или серию фотографий с камеры, ограничение списка сократит время работы и упростит разбор результатов:

# После запуска photorec - меню навигации:
# 1. Select disk -> /dev/sda
# 2. Select partition -> [P5] на нужном разделе
# 3. File Opt -> отключить всё, оставить только нужные форматы (s - снять, enter - включить/выключить)
# 4. Search -> ext2/ext3 (для ext4 этот же выбор)
# 5. Free / Whole - "Free" быстрее, "Whole" найдёт больше
# 6. Выбрать папку назначения на другом диске - Y для подтверждения

PhotoRec работает медленно. Полное сканирование терабайтного диска занимает от нескольких часов до суток. Зато результат стабильнее, чем у extundelete - сигнатурный поиск не зависит от состояния журнала и не страдает от того, что инод уже переиспользован. На разделах, где extundelete возвращает 0 recoverable inodes, photorec часто вытаскивает значительный объём данных.

TestDisk и его роль в восстановлении именно файлов

Несмотря на то, что testdisk и photorec идут одним пакетом, у них разные задачи. TestDisk создавался для восстановления потерянных разделов и таблиц разделов после повреждения MBR/GPT. Функция undelete у него тоже есть, но работает только на FAT, exFAT и NTFS. Для ext4 функция undelete в testdisk отсутствует, и интерфейс прямо об этом сообщает при попытке её использовать.

Это распространённая путаница, на которой обжигаются те, кто читает первый попавшийся туториал. На форумах cgsecurity (разработчиков testdisk) этот вопрос задают регулярно, и ответ всегда один: для ext4 используйте photorec или extundelete, в testdisk такой функциональности нет. Запускать testdisk имеет смысл в двух случаях. Первый - если случайно удалена целая партиция, и нужно восстановить таблицу разделов. Второй - если файлы были на FAT-флешке или NTFS-разделе.

# Запуск testdisk для восстановления разделов
sudo testdisk /dev/sda

# В интерактивном меню:
# - Create new log file (Yes)
# - Выбор диска
# - Выбор типа таблицы разделов (обычно автоопределяется)
# - Analyse -> Quick Search -> Deeper Search (если нужно)
# - При нахождении удалённой партиции: Write для записи

# Для FAT/NTFS - вход в Advanced -> Undelete

Связка testdisk + photorec в реальности применяется в двух разных сценариях, и понимание этого экономит часы потерянного времени. Для восстановления удалённых файлов на ext4 нужен только photorec. Testdisk вспоминается, когда после неудачного решения с разметкой диска пропала целая партиция.

Debugfs как точечный инструмент для тех, кто знает номер инода

Когда extundelete не справился, а тратить сутки на photorec неохота - есть третий путь через debugfs. Это низкоуровневый отладчик файловой системы из пакета e2fsprogs, который умеет читать сырую структуру ext2/3/4. С его помощью можно вывести список недавно удалённых инодов и попробовать достать конкретный.

# Открытие раздела в debugfs (read-only для безопасности)
sudo debugfs /dev/sda5

# Внутри debugfs - список удалённых инодов
debugfs: lsdel

# Вывод покажет таблицу с инодами, размером и временем удаления
# Inode  Owner  Mode   Size      Blocks   Time deleted
# 524289 1000   100644 1048576   256/256  Sun Jan 15 14:23:42 2026

# Дамп конкретного инода в файл
debugfs: dump <524289> /tmp/recovered_file

# Выход
debugfs: quit

Подход работает только если соответствующий инод ещё не был переиспользован системой. После удаления файла его инод попадает в пул свободных, и любой новый файл может занять его место с полным затиранием информации. На свежем удалении, когда раздел сразу же отмонтирован, lsdel часто показывает то, что нужно. На системе, которая продолжала работать после удаления, lsdel может выдать пустой список или показать инод, который уже занят чем-то другим.

Главное преимущество debugfs - точечность. Если известен примерный размер файла и время удаления, в выводе lsdel находится нужный инод по этим параметрам, и дамп выполняется секунды. Никакого многочасового сканирования, никаких гигабайт мусора в результатах.

Реалистичная оценка шансов на восстановление в разных сценариях

Цифры успешного восстановления сильно зависят от сценария, и абстрактных ответов вроде "вероятность 50 на 50" в этой области не существует. Несколько типичных ситуаций с реальной статистикой из практики.

Удаление одного файла в домашней папке, раздел сразу отмонтирован, прошло меньше пяти минут. Шансы вернуть файл целиком через extundelete - около 80-90 процентов для файлов до 50 МБ, около 60-70 процентов для крупных файлов из-за фрагментации. Если повезло и файл лежит непрерывно, photorec тоже вытащит его с большой вероятностью.

Удаление папки с десятками файлов несколько часов назад, система продолжала работать. Шансы через extundelete падают до 30-50 процентов, и оригинальные имена восстанавливаются только для части файлов. PhotoRec вытащит больше по объёму, но без структуры папок и без имён.

Удаление файла на корневом разделе работающей системы, прошли сутки. Шансы вернуть конкретный файл - 10-30 процентов в лучшем случае. Фоновые процессы, логи, апдейты пакетов уже наверняка затёрли часть нужных блоков. PhotoRec поможет, но результат окажется сильно частичным, особенно для крупных файлов.

Удаление на SSD с включённым TRIM. Это худший сценарий и фактически приговор данным. TRIM сообщает контроллеру SSD, какие блоки можно физически очистить для подготовки к новой записи, и контроллер делает это в фоне в течение секунд или минут. После срабатывания TRIM на удалённых блоках там физически нет данных - читается ноль. Ни extundelete, ни photorec, ни любой другой инструмент не помогут.

Проверить, включён ли TRIM на разделе, можно командой:

# Проверка включения TRIM в опциях монтирования
mount | grep discard

# Проверка наличия таймера periodic fstrim
systemctl status fstrim.timer

# Просмотр последнего срабатывания
journalctl -u fstrim.service --since "1 week ago"

Если TRIM работает в режиме discard в опциях монтирования - блоки очищаются сразу при удалении. Если работает через fstrim.timer (по умолчанию раз в неделю на современных дистрибутивах) - блоки очищаются пакетно. Между удалением и следующим срабатыванием fstrim шансы на восстановление сохраняются. После - нет.

Превентивные меры, которые экономят нервы лучше любого восстановления

Лучшее восстановление - то, которое не понадобилось. Несколько привычек, которые освоить намного дешевле, чем разбираться с потерей данных постфактум.

Первое - алиас на rm, перехватывающий случайные удаления. Утилита trash-cli реализует аналог корзины для командной строки. Удалённые файлы попадают в ~/.local/share/Trash/files/ и могут быть восстановлены простой командой. Привыкнуть переучивать пальцы стоит один раз - дальше работает автоматически:

# Установка
sudo apt install trash-cli

# Алиас в ~/.bashrc или ~/.zshrc
alias rm='trash-put'
alias ll='ls -lh'

# Восстановление из корзины
trash-restore

# Просмотр содержимого
trash-list

# Реальное удаление, когда уверен
trash-empty

Второе - снапшоты на уровне файловой системы. Btrfs и ZFS поддерживают атомарные снапшоты, которые делаются за миллисекунды и позволяют откатиться к состоянию диска на любой момент в прошлом. Для btrfs утилита snapper автоматизирует процесс - создаёт снапшоты по расписанию и при операциях apt. Восстановление файла из снапшота занимает секунды и не зависит от того, что система делала после удаления.

Третье - резервные копии. Старая истина: данные существуют, только если есть хотя бы две независимые копии. Утилиты вроде restic, borg или rsync позволяют делать инкрементальные бэкапы на внешний диск или удалённый сервер. Регулярный бэкап превращает потерю файла из катастрофы в неудобство на пять минут.

Четвёртое и самое простое - привычка проверять команду перед нажатием Enter. Особенно rm -rf с переменными окружения. Бесчисленные истории про серверы, очищенные командой rm -rf "$VAR/", где $VAR оказалась пустой, происходят из-за одного и того же - нажатия Enter без перечитывания строки. Полсекунды паузы окупаются годами.

Удалённый файл на Linux - не приговор, но и не гарантированно решаемая задача. Скорость реакции, понимание устройства файловой системы и выбор правильного инструмента под конкретный сценарий определяют, окажется ли потеря временной или окончательной. Знать процедуру наизусть стоит не на случай катастрофы, а как часть базовой технической гигиены, которая рано или поздно пригодится каждому, кто работает с системой через терминал.