Представьте что вы весь день играли со звуковым файлом, и добились прекрасного звучания, потом решили что надо его переместить в другую папку и случайно удалил его. Обидно? Не расстраивайтесь, это случается с каждым, и к счастью есть способ восстановить этот файл.
Вкратце: файл это только привязка имени к определённому узлу, который содержит все свойства файла, навроде прав доступа и адресов блоков данных в которых расположен файл. Когда вы удаляете файл - вы удаляете только эту связь, но не узел непосредственно. Другие процессы (например ваш аудио-проигрыватель) ещё могут обращаться к этому узлу. Реально файл удаляется только тогда, когда уже ни одни процесс не использует его.
Эта особенность - ваш шанс. Если какой-то процесс всё ещё держит файл, хотя он и отсутствует уже в оглавлении каталога - вы можете его восстановить.
Здесь в игру вступает псевдо-фс /proc. Каждый процесс на этой файловой системе имеет свой каталог, в котором есть много всего, в том числе подкаталог fd ("file descriptor"), содержащий ссылки на все узлы открытых файлов, даже если они уже были удалены - их копия будет здесь:
/proc/process id/fd/file descriptor
Чтобы знать где именно - вам нужно получить id процесса и дескриптор файла. Получить их вы можете с помощью команды lsof.
Получив нужную нужную информацию вы можете сразу скопировать файл и работа завершена.
Лучше всего это продемонстрировать на примере. Сначала создадим текстовый файл:
$ man lsof | col -b > myfile
Попытайтесь просмотреть содержимое только что созданного файла:
$ less myfile
Вы должны увидеть текст справочной страницы по lsof. Теперь нажмите Ctrl+Z для приостановки less и возврата в командную строку. Затем убедитесь что файл существует:
$ ls -l myfile -rw-r--r-- 1 jimbo jimbo 114383 Oct 31 16:14 myfile $ stat myfile File: `myfile' Size: 114383 Blocks: 232 IO Block: 4096 regular file Device: 341h/833d Inode: 1276722 Links: 1 Access: (0644/-rw-r--r--) Uid: ( 1010/ jimbo) Gid: ( 1010/ jimbo) Access: 2006-10-31 16:15:08.423715488 -0400 Modify: 2006-10-31 16:14:52.684417746 -0400 Change: 2006-10-31 16:14:52.684417746 -0400
Как видите файл на месте. Теперь удалите его:
$ rm myfile $ ls -l myfile ls: myfile: No such file or directory $ stat myfile stat: cannot stat `myfile': No such file or directory $
Теперь вы не должны завершать процесс, использующий файл, потому что как только это случиться - файл будет полностью удалён. Сейчас команда less находиться в фоне и использует наш файл. Но если бы это был например аудиоредактор или проигрыватель - вам нужно как-то зафиксировать процесс. Например приостановив воспроизведение.
Начинаем восстанавливать файл. Для начала посмотрим на вывод lsof:
$ lsof | grep myfile less 4158 jimbo 4r REG 3,65 114383 1276722 /home/jimbo/myfile (deleted)
В первом столбце видно название команды, использующей файл, второй столбец - id процесса, четвёртый - дескриптор файла. Теперь вы знаете что процесс 4158 использует ваш файл, который имеет дескриптор 4 (буква r означает regular - обычный файл). Осталось только скопировать файл из каталога /proc.
Если вам кажется что использование команды cp с флагом -a хорошая идея то вы ошибаетесь. Поскольку вы скопируете сломанную связь к файлу. Т.е. он по прежнему будет удалён:
$ ls -l /proc/4158/fd/4 lr-x------ 1 jimbo jimbo 64 Oct 31 16:18 /proc/4158/fd/4 -> /home/jimbo/myfile (deleted) $ cp -a /proc/4158/fd/4 myfile.wrong $ ls -l myfile.wrong lrwxr-xr-x 1 jimbo jimbo 24 Oct 31 16:22 myfile.wrong -> /home/jimbo/myfile (deleted) $ file myfile.wrong myfile.wrong: broken symbolic link to `/home/jimbo/myfile (deleted)' $ file /proc/4158/fd/4 /proc/4158/fd/4: broken symbolic link to `/home/jimbo/myfile (deleted)'
Вместо этого вам стоит использовать cp без лишних параметров:
$ cp /proc/4158/fd/4 myfile.saved
После этого стоит убедиться что всё хорошо:
$ ls -l myfile.saved -rw-r--r-- 1 jimbo jimbo 114383 Oct 31 16:25 myfile.saved $ man lsof | col -b > myfile.new $ cmp myfile.saved myfile.new
Нет никаких сообщений об ошибке от cmp, значит файл восстановился правильно!
Anonymous 2013-09-25 22:32:03 (#)