Файлы в Linux удаляются с помощью системного вызова unlink. Он удаляет имя из файловой системы. Если это имя было последней ссылкой на файл и больше нет процессов, которые держат этот файл открытым, данный файл удаляется и место, которое он занимает, освобождается для дальнейшего использования. Если имя было последней ссылкой на файл, но какие-либо процессы всё ещё держат этот файл открытым, файл будет оставлен, пока последний файловый дескриптор, указывающий на него, не будет закрыт.
Исходя из этой информации можно легко восстанавливать удалённые файлы, удерживаемые процессом. Выполним простой эксперимент с помощью bash. Создадим тестовый скрипт именем script.sh следующего содержания:
#!/bin/bashsleep 30000exitУстанавливаем бит исполняемости:
# chmod u+x ./script.shЗапускаем скрипт в фоне и удаляем.
# ./script.sh &# rm -f ./script.shИтак, у нас есть процесс оболочки, который удерживает файл скрипта. Имени уже нету, но есть дескриптор, с которым ассоциирован файл. Нужно получить дескриптор файла. В этом нам поможет команда lsof:
# lsof -c script.shВ выводе нас интересует PID - идентификатор процесса и FD - дескриптор, ассоциированный со скриптом:
script.sh 17871 root 255r REG 8,1 30 8400545 /tmp/script.sh (deleted)Читаем содержимое файла скрипта.
# cat /proc/17871/fd/255Перенаправляем вывод cat в файл:
# cat /proc/17871/fd/255 > new_script.shПолучаем наш исходный скрипт, который удалили.
Поднимаем процесс из фона и уничтожаем.
# fgCTRL+CТеоретически таким образом можно восстановить удалённые файлы виртуальных машин. Я не раз получал вопросы по этому поводу. Некоторые умудряются по ошибке удалить исходный файл VM, а потом через 2 недели заметить это. При этом машина всё это время успешно работает.
Сохраните заметку в закладки, может пригодиться в самом неожиданном случае. У меня бывало, что по ошибке удалял конфиг работающей программы. Казалось бы, вот он только что был, ты его грохнул, а как вернуть, не понимаешь.
#terminal #restore