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/42
wobei 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).
lsof / | awk '(/deleted/||/abc.txt/) {print "FD :-",$4,"| File Name:-",$9}'