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

Предположим, что файл журнала 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 ), так что мне не нужно вручную спрашивать кого-то, где файл был расположен оригинально и помещать его туда.

One Solution collect form web for “восстановить удаленный файл, открытый apache?”

Если файл был удален, но все еще открыт, это значит, что файл все еще существует в файловой системе (у него есть индексный индекс ), но имеет количество ссылок на строку 0. Поскольку ссылка на файл отсутствует, вы не можете открыть его по имени , Нет возможности открывать файл также inode.

Невозможно обнаружить файл через свою файловую систему, и особенно не искать файл в каталоге, где он был последним. Запись в каталог не прошла. Остается только файл. Вы можете перейти к файлу с помощью отладчика файловой системы, но для этого требуются права на root, и его трудно использовать и подвергать ошибкам.

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).

  • Как мне выполнить фоновое представление / возвращение раньше?
  • Отложить переменное расширение до подоболочки
  • Canot удаляет символические ссылки: после перезагрузки появляются символические ссылки
  • Как запустить несколько процессов с помощью одной команды?
  • Ожидание / dev / sda1, чтобы стать доступным, с таймаутом, в сценарии оболочки
  • Передать переменную в директиву выполнения без выполнения содержимого переменной
  • Как настроить отдельную среду bash с помощью только утилит GNU на OS X?
  • Ожидание сбоя сценария при запуске из cron, но работает при запуске вручную
  • Разноцветный Греп
  • Получить последнюю минуту из строк из списка
  • Поиск файлов по кодировке символов
  • Linux и Unix - лучшая ОС в мире.