відновлення видаленого файлу, відкритого апачем?


10

Припустимо, файл журналу apache видаляється, але його відкрито apache; то це я роблю:

pid=$(lsof | grep text.txt | awk '/deleted/ {print $2}')
fd=$(lsof | grep text.txt | awk '/deleted/ {print $4}' | grep -oE "[[:digit:]]{1,}")

cp /proc/$pid/fd/$fd directorytobecopied/testfile.txt

Це те, що я роблю, щоб відновити файл і повернути його туди, де він був. Чи є простіший спосіб зробити це, тому що вищезгаданий код не виглядає добре. Крім того, як я знаю, звідки був видалений файл ( directorytobecopied ), так що мені не доведеться вручну запитувати когось, де цей файл був оригінальним, і помістити його туди.


lsof / | awk '(/deleted/||/abc.txt/) {print "FD :-",$4,"| File Name:-",$9}'
Рахул Патіль

Відповіді:


14

Якщо файл було видалено, але він все ще відкритий, це означає, що файл все ще існує у файловій системі (у нього є inode ), але кількість жорстких посилань становить 0. Оскільки немає посилання на файл, ви не можете відкрити його по імені . Немає можливості відкривати файл і за допомогою inode.

Немає способу виявити файл через його файлову систему, і особливо немає можливості шукати файл у каталозі, де він останній був. Запис у каталог відсутній. Залишилося лише сам файл. Ви можете дістатися до файлу за допомогою налагоджувача файлової системи, але для цього потрібні кореневі дозволи та важкі у використанні та схильні до помилок.

Linux відкриває відкриті файли через спеціальні символічні посилання під /proc. Ці посилання називаються /proc/12345/fd/42там, де 12345 є PID процесу, а 42 - номер дескриптора файлу в цьому процесі. Програма, що працює з тим самим користувачем, що і цей процес, може отримати доступ до файлу (дозволи на читання / запис / виконання такі ж, як у вас, коли файл був видалений).

Ім'я, під яким було відкрито файл, все ще видно в цілі символічного посилання: якщо файл був /var/log/apache/foo.log, то ціль посилання є /var/log/apache/foo.log (deleted). (Якщо файл було перейменовано після його відкриття, ціль символьного посилання може відображати перейменування.)

Таким чином, ви можете відновити вміст відкритого видаленого файлу, враховуючи PID процесу, який він відкриває, і дескриптор, на який він відкритий, як це:

recover_open_deleted_file () {
  old_name=$(readlink "$1")
  case "$old_name" in
    *' (deleted)')
      old_name=${old_name%' (deleted)'}
      if [ -e "$old_name" ]; then
        new_name=$(TMPDIR=${old_name%/*} mktemp)
        echo "$oldname has been replaced, recovering content to $new_name"
      else
        new_name="$old_name"
      fi
      cat <"$1" >"$new_name";;
    *) echo "File is not deleted, doing nothing";;
  esac
}
recover_open_deleted_file "/proc/$pid/fd/$fd"

Якщо ви знаєте лише ідентифікатор процесу, але не дескриптор, ви можете відновити всі файли за допомогою

for x in /proc/$pid/fd/*; do
  recover_open_deleted_file "$x"
done

Якщо ви також не знаєте ідентифікатора процесу, ви можете шукати серед усіх процесів:

for x in /proc/[1-9]*/fd/*; do
  case $(readlink "$x") in
    /var/log/apache/*) recover_open_deleted_file "$x";;
  esac
done

Ви також можете отримати цей список шляхом аналізу результатів lsof, але він не простіший, ні надійніший, ні більш портативний (це все одно для Linux).


Ви можете відкрити / proc / x / fd / y для читання чи письма незалежно від того, чи він відкритий для читання чи запису.
Стефан Шазелас

чому Unix OS дозволяє видалити файл при його відкритті ... в той час як ми не можемо це зробити в windows. чи є якесь пояснення
munish

@munish Windows починається з спільної багатозадачної моделі: якщо програма не поводиться, вона може привести до роботи системи. Більшість проблем уже вирішено, але Windows все ще дозволяє програмі викрасти файл: якщо файл відкритий, його не можна перейменовувати чи видаляти. Unix не дозволяє цього: видалення або перейменування файлу є ортогональним для відкриття.
Жиль "ТАК - перестань бути злим"

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