Восстановление открытого файла

У меня есть интересная проблема, которая может иметь или не иметь решения, но я хотел бы иметь один, если это возможно:

В Solaris был удален открытый файл журнала, который по-прежнему сохраняется во время выполнения процесса, но теперь недоступен для всех других инструментов, таких как cat , tail и т. Д.

Есть ли способ восстановить запись в каталоге этого файла, пока все работает?

One Solution collect form web for “Восстановление открытого файла”

Это выполнимо, с некоторыми хаками и ограничениями (вам нужны привилегии root).

Сначала найдите, какой файловый дескриптор использует приложение для записи файла журнала, затем создайте символическую ссылку в предыдущем местоположении файла журнала и указав на запись файла / proc, например:

 ln -s /var/tmp/file.log /proc/12345/fd/3 

Первое ограничение состоит в том, что если файл был открыт только для записи процессом, его разрешение не позволит непривилегированному пользователю читать его содержимое. Однако root и пользователи с привилегией file_dac_read не будут затронуты. Кроме того, вы можете использовать процесс для копирования содержимого файла с помощью tail как говорит Жиль в своем комментарии. например:

 tail -c +1 -f /proc/12345/fd/5 > /var/tmp/file.log 

Вторая проблема заключается в том, что весь файл будет потерян ( ln -s ) или его часть ( tail -c 1 -f ), когда процесс либо закрывает его, либо завершает работу.

Обходным путем является использование программы, которая контролирует это событие и создает резервную копию файла до того, как на самом деле будет вызван закрытие.

Вероятными инструментами для работы являются dtrace, truss, mdb или dbx.

Вот доказательство концепции, использующее dtrace в Solaris 10.

 #!/bin/ksh # # This dtrace script is monitoring a file descriptor for a given process # and copy its content to the given path when the file is closed. # pid=${1:?"$0: Usage: pid fd path"} fd=${2:?} path=${3:?} [[ -f $path ]] && { echo "$path exists"; exit 1; } dtrace -w -n ' syscall::close:entry /pid=='$pid' && arg0=='$fd'/ { stop(); system("cp /proc/%d/fd/%d %s",pid,arg0,"'"$path"'"); system("prun %d",pid); exit(0); }' 
  • Проверка времени с помощью регулярного выражения
  • Как НЕ загружать драйверы Solaris SPARC при загрузке
  • Что означает «Недопустимый аргумент» в Solaris?
  • Solaris 11 и vim F вместо конца
  • Установка Solaris 10 на KVM постоянно перезагружается
  • Solaris11: альтернатива гипервизору xVM?
  • Как связать emacs прервать ключ
  • Что означает @ в имени хоста в файле .rhosts в Solaris?
  • Копирование только различий?
  • Solaris grep и регулярные выражения?
  • Изменение цвета терминала в Solaris 10
  • Linux и Unix - лучшая ОС в мире.