gelöschte Datei wiederherstellen, die von Apache offen gehalten wird?

10

Angenommen, eine Apache-Protokolldatei wird gelöscht, aber von Apache offen gehalten. dann mache ich folgendes:

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

Dies ist, was ich tue, um die Datei wiederherzustellen und wieder dort abzulegen, wo sie war. Gibt es eine einfachere Möglichkeit, dies zu tun, da der obige Code nicht gut aussieht? Außerdem, woher weiß ich, woher die Datei gelöscht wurde ( Verzeichnis , das kopiert wurde), damit ich niemanden manuell fragen muss, wo sich die Datei ursprünglich befindet, und sie dort ablegen muss.

Munish
quelle
lsof / | awk '(/deleted/||/abc.txt/) {print "FD :-",$4,"| File Name:-",$9}'
Rahul Patil

Antworten:

14

Wenn eine Datei gelöscht wurde, aber noch geöffnet ist, bedeutet dies, dass die Datei noch im Dateisystem vorhanden ist (sie hat einen Inode ), aber eine feste Linkanzahl von 0. Da kein Link zur Datei vorhanden ist, können Sie sie nicht namentlich öffnen . Es gibt auch keine Möglichkeit, eine Datei per Inode zu öffnen.

Es gibt keine Möglichkeit, die Datei über das Dateisystem zu ermitteln, und insbesondere keine Möglichkeit, die Datei in dem Verzeichnis zu suchen, in dem sie sich zuletzt befand. Der Verzeichniseintrag ist weg. Alles was bleibt ist die Datei selbst. Sie können mit einem Dateisystem-Debugger auf die Datei zugreifen, dies erfordert jedoch Root-Berechtigungen und ist schwer zu verwenden und fehleranfällig.

Linux macht offene Dateien durch spezielle symbolische Links unter verfügbar /proc. Diese Links werden aufgerufen, /proc/12345/fd/42wobei 12345 die PID eines Prozesses und 42 die Nummer eines Dateideskriptors in diesem Prozess ist. Ein Programm, das als derselbe Benutzer wie dieser Prozess ausgeführt wird, kann auf die Datei zugreifen (die Lese- / Schreib- / Ausführungsberechtigungen entsprechen denen, die Sie beim Löschen der Datei hatten).

Der Name, unter dem die Datei geöffnet wurde, ist im Ziel des symbolischen Links noch sichtbar: Wenn die Datei war /var/log/apache/foo.log, ist das Ziel des Links /var/log/apache/foo.log (deleted). (Wenn die Datei nach dem Öffnen umbenannt wurde, spiegelt das Ziel des Symlinks möglicherweise die Umbenennung wider.)

Auf diese Weise können Sie den Inhalt einer geöffneten gelöschten Datei anhand der PID eines Prozesses, in dem sie geöffnet ist, und des Deskriptors, auf dem sie geöffnet ist, wie folgt wiederherstellen:

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"

Wenn Sie nur die Prozess-ID kennen, aber nicht den Deskriptor, können Sie alle Dateien mit wiederherstellen

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

Wenn Sie auch die Prozess-ID nicht kennen, können Sie zwischen allen Prozessen suchen:

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

Sie können diese Liste auch erhalten, indem Sie die Ausgabe von analysieren lsof, sie ist jedoch weder einfacher noch zuverlässiger noch portabler (dies ist ohnehin Linux-spezifisch).

Gilles 'SO - hör auf böse zu sein'
quelle
Sie können / proc / x / fd / y zum Lesen oder Schreiben öffnen, unabhängig davon, ob x es zum Lesen oder Schreiben geöffnet hat.
Stéphane Chazelas
Warum erlaubt das Unix-Betriebssystem das Löschen der Datei, wenn es geöffnet ist ... während wir es in
Windows
@munish Windows ging von einem kooperativen Multitasking-Modell aus: Wenn sich eine Anwendung schlecht verhält, kann das System heruntergefahren werden. Die meisten Probleme wurden inzwischen behoben, aber Windows erlaubt einer Anwendung weiterhin, eine Datei zu entführen: Solange die Datei geöffnet ist, kann sie nicht umbenannt oder gelöscht werden. Unix erlaubt dies nicht: Das Löschen oder Umbenennen einer Datei ist orthogonal zum Öffnen.
Gilles 'SO - hör auf böse zu sein'
1
Sie haben gerade Muses Ursprung der Symmetrie für mich gespeichert! Vielen Dank tausendmal!
Dotancohen