odzyskiwanie skasowanego pliku otwartego przez apache?

10

Załóżmy, że plik dziennika apache został usunięty, ale jest utrzymywany jako otwarty przez apache; to właśnie robię:

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

To właśnie robię, aby odzyskać plik i umieścić go z powrotem tam, gdzie był. Czy istnieje prostszy sposób, aby to zrobić, ponieważ powyższy kod nie wygląda dobrze. Co więcej, skąd mam wiedzieć, skąd plik został usunięty ( directorytobecopied ), żebym nie musiał ręcznie pytać kogoś, gdzie plik został pierwotnie zlokalizowany i odłożyć go z powrotem.

Munish
źródło
lsof / | awk '(/deleted/||/abc.txt/) {print "FD :-",$4,"| File Name:-",$9}'
Rahul Patil,

Odpowiedzi:

14

Jeśli plik został usunięty, ale nadal jest otwarty, oznacza to, że plik nadal istnieje w systemie plików (ma i- węzeł ), ale ma twardą liczbę linków równą 0. Ponieważ nie ma łącza do pliku, nie można go otworzyć według nazwy . Nie ma też możliwości otwarcia pliku przez i-węzeł.

Nie ma sposobu, aby odkryć plik poprzez jego system plików, a zwłaszcza nie ma sposobu, aby wyszukać plik w katalogu, w którym był ostatnio. Wpis w katalogu zniknął. Pozostaje tylko sam plik. Do pliku można dostać się za pomocą debugera systemu plików, ale wymaga to uprawnień administratora i jest trudny w użyciu i podatny na błędy.

Linux udostępnia otwarte pliki za pomocą specjalnych dowiązań symbolicznych pod /proc. Te łącza są wywoływane, gdy /proc/12345/fd/4212345 jest PID procesu, a 42 to liczba deskryptorów plików w tym procesie. Program działający jako ten sam użytkownik co ten proces może uzyskać dostęp do pliku (uprawnienia do odczytu / zapisu / wykonania są takie same, jak w przypadku usunięcia pliku).

Nazwa, pod którą plik został otwarty, jest nadal widoczna w celu dowiązania symbolicznego: jeśli plik był /var/log/apache/foo.log, to celem dowiązania jest /var/log/apache/foo.log (deleted). (Jeśli nazwa pliku została zmieniona po jego otwarciu, cel dowiązania symbolicznego może odzwierciedlać zmianę nazwy).

W ten sposób możesz odzyskać zawartość otwartego usuniętego pliku, biorąc pod uwagę PID procesu, który go otworzył i deskryptor, na którym jest otwarty w następujący sposób:

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"

Jeśli znasz tylko identyfikator procesu, ale nie deskryptor, możesz odzyskać wszystkie pliki za pomocą

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

Jeśli nie znasz identyfikatora procesu, możesz przeszukać wszystkie procesy:

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

Możesz także uzyskać tę listę, analizując dane wyjściowe lsof, ale nie jest to prostsze, bardziej niezawodne ani przenośne (w każdym razie jest to specyficzne dla Linuksa).

Gilles „SO- przestań być zły”
źródło
Możesz otworzyć / proc / x / fd / y do czytania lub pisania, niezależnie od tego, czy x ma je otwarte do czytania lub pisania.
Stéphane Chazelas,
dlaczego uniksowy system operacyjny pozwala na usunięcie pliku, gdy jest otwarty ... podczas gdy nie możemy tego zrobić w systemie Windows. czy jest jakieś wytłumaczenie
poniedziałek 23.12
@Munish Windows zaczął od modelu wielozadaniowości opartej na współpracy: jeśli aplikacja źle się zachowuje, może to doprowadzić do awarii systemu. Większość problemów została już rozwiązana, ale system Windows nadal pozwala aplikacji na przejęcie pliku: dopóki plik jest otwarty, nie można zmienić jego nazwy ani usunąć. Unix na to nie pozwala: usuwanie lub zmiana nazwy pliku jest ortogonalne przed otwarciem.
Gilles „SO- przestań być zły”
1
Właśnie dla mnie zapisałeś Origin of Symmetry Muse! Dziękuję tysiąc razy!
dotancohen