Як відновити видалений файл, якщо він все-таки відкривається деяким процесом?


19
$ cat important_file > /dev/null &
[1] 9711
$ rm important_file 
$ killall -STOP cat

[1]+  Stopped                 cat important_file > /tmp/p
$ ls -l /proc/`pidof cat`/fd/
total 0
lrwx------ 1 vi vi 64 May 13 20:32 0 -> /dev/pts/29
l-wx------ 1 vi vi 64 May 13 20:32 1 -> /tmp/p
lrwx------ 1 vi vi 64 May 13 20:32 2 -> /dev/pts/29
lr-x------ 1 vi vi 64 May 13 20:32 3 -> /home/vi/important_file (deleted)

Як відновити це important_file?

Я спробував щось подібне

injcode -m dup2 -ofd=3 -ofilename=/tmp/recovered_file -oflags=O_CREAT $PID_OF_CAT

але це нічого не робить.

Відповіді:


11

Якщо / home - це NFS, в / home / vi з'явиться файл .nfsNNNNNNNNNN, до якого ви можете отримати доступ / скопіювати. Якщо додому є локальною файловою системою, ви можете зробити те ж саме через посилання / proc / PID / fd / 3:

cp /proc/PID/fd/3 /tmp/recovered_file

Якщо ви хочете фактично відновити файл, ось повідомлення в блозі на цю тему.


1
Гаразд, мене це збентежило readlink /proc/13381/fd/3-> "/ home / vi / важливий_файл (видалено)" і /home/vi/important_file\ \(deleted\)явно не існує.
Ві.

22

... краще, ніж копіювати в даний момент (і збирати лише знімок вмісту файлу лише цього часу) - це " tail -f" цей файл у новий файл:

tail -c +0 -f /proc/PIDofProgram>/fd/# > /new/path/to/file

(завдяки обережним програмістам хвоста, які працюватимуть навіть із двійковим виведенням.)

Під час його виконання tail -fсам зберігає файл відкритим, безпечно не даючи йому очистити диск з диска після завершення початкової програми. Таким чином, не стопори tail -fвідразу після ваших первинних цілей програми , - перевірте tail'ed /new/path/to/fileперший чи це те , що ви хочете. Якщо це не (або не задовольняє будь-яку іншу причину), ви можете скопіювати оригінальний файл знову, але на цей раз після того, як усі записи до нього завершиться програмою "Програма" та з все ще працюючого tail -f"/ proc / PIDoftail / fd / каталог.


3
Що щодо створення жорсткого посилання на / proc / PIDofProgram> / fd / #?
бекко

2
@becko Invalid cross-device link.
Каміль Маціоровський

10

Використовуйте lsof, щоб знайти номер inode, і налагодження відтворити жорстке посилання на нього. Наприклад:

# lsof -p 12345 | grep /var/log/messages
syslogd 12345 root    3w   REG                8,3    3000    987654 /var/log/messages (deleted)
# mount | grep var
/dev/sda2 on /var type ext3 (rw)
# debugfs -w /dev/sda2
debugfs: cd log
debugfs: ln <987654> tmp
debugfs: mi tmp
                      Mode    [0100600] 
                   User ID    [0] 
                  Group ID    [0] 
                      Size    [3181271] 
             Creation time    [1375916400] 
         Modification time    [1375916322] 
               Access time    [1375939901]
             Deletion time    [9601027] 0
                Link count    [0] 1
               Block count    [6232] 
                File flags    [0x0] 
...snip...
debugfs:  q
# mv /var/log/tmp /var/log/messages
# ls -al /var/log/messages
-rw------- 0 root root 3301 Aug  8 10:10 /var/log/messages

Перш ніж скаржитися, я підробив вищезгадану стенограму, оскільки у мене зараз немає видаленого файлу ;-)

я використовую mi для скидання часу видалення та підрахунку посилань до значущих значень (0 та 1 відповідно), але це не працює належним чином - ви можете бачити, що кількість посилань залишається на нулі дюйма ls. Я думаю, що ядро ​​може кешувати дані inode. Вам, ймовірно, слід fsck при першій же можливості після використання налагоджень, щоб бути в безпечній стороні.

На мій досвід, ви повинні створити посилання, використовуючи тимчасове ім’я файлу, а потім перейменувати його на власне ім’я. Пов’язання його безпосередньо з початковим іменем файлу, здається, може призвести до пошкодження каталогу. YMMV!


Чому саме ви це пропонуєте, якщо воно справді не працює належним чином і спричинює пошкодження системи? Я думаю, у вас повинна бути більш яскрава відмова від відповідальності, що це просто WiP, і його не слід реально намагатись у виробництві.
cnst

3

Ви можете просто cpфайл, тобто:

cp /proc/<pid>/fd/<fdno> /new/path/to/file

Звичайно, якщо файл все ще змінюється, ви зіткнетеся з таким підходом.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.