восстанавливать удаленный файл, открытый apache?

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

Это то, что я делаю, чтобы восстановить файл и вернуть его туда, где он был. Есть ли более простой способ сделать это, потому что приведенный выше код не выглядит хорошо. Кроме того, как мне узнать, откуда был удален файл ( каталог, скопированный), чтобы мне не приходилось вручную спрашивать кого-то, где файл был изначально найден, и помещать его туда.

Munish
источник
lsof / | awk '(/deleted/||/abc.txt/) {print "FD :-",$4,"| File Name:-",$9}'
Рахул Патил

Ответы:

14

Если файл был удален, но все еще открыт, это означает, что файл все еще существует в файловой системе (он имеет индекс ), но имеет жесткое число ссылок, равное 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 для чтения или записи независимо от того, открыт ли x для чтения или записи.
Стефан Шазелас
почему операционная система Unix допускает удаление файла при его открытии ... в то время как мы не можем сделать это в windows.is есть какое-либо объяснение
munish
@munish Windows начиналась с модели совместной многозадачности: если приложение плохо себя ведет, оно может привести к выходу системы из строя. Большинство проблем уже исправлено, но Windows все еще позволяет приложению захватывать файл: пока файл открыт, его нельзя переименовывать или удалять. Unix не позволяет этого: удаление или переименование файла является ортогональным по отношению к его открытию.
Жиль "ТАК - перестать быть злым"
1
Вы только что сохранили для меня Происхождение симметрии Muse! Спасибо тысячу раз!
dotancohen