Wie kann ich gelöschte Dateien wiederherstellen, wenn sie noch von einem Prozess geöffnet werden?

$ cat important_file > /dev/null &
[1] 9711
$ rm important_file 
$ killall -STOP cat

[1]+  Stopped                 cat important_file > /tmp/p
$ ls -l /proc/`pidof cat`/fd/
total 0
lrwx------ 1 vi vi 64 May 13 20:32 0 -> /dev/pts/29
l-wx------ 1 vi vi 64 May 13 20:32 1 -> /tmp/p
lrwx------ 1 vi vi 64 May 13 20:32 2 -> /dev/pts/29
lr-x------ 1 vi vi 64 May 13 20:32 3 -> /home/vi/important_file (deleted)

Wie kann ich dieses important_file wiederherstellen?

Ich habe so etwas versucht wie

injcode -m dup2 -ofd=3 -ofilename=/tmp/recovered_file -oflags=O_CREAT $PID_OF_CAT

Aber es tut nichts.

Author: djsmiley2kStaysInside, 2011-05-13

5 answers

Wenn / home NFS ist, wird es ein .nfsNNNNNNNNNN Datei in / home / vi, auf die Sie zugreifen / kopieren können. Wenn home ein lokales Dateisystem ist, sollten Sie dasselbe über den Link /proc/PID/fd/3 tun können:

cp /proc/PID/fd/3 /tmp/recovered_file

Wenn Sie wollen, um tatsächlich undelete die Datei, hier ist ein blog post zum Thema.

 15
Author: Mark Johnson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/techietown.info/template/agent.layouts/content.php on line 61
2011-05-13 23:53:05

... besser als zu einem bestimmten Zeitpunkt zu kopieren (und nur den Schnappschuss des Dateiinhalts dieser Zeit zu sammeln), ist es, diese Datei in eine neue Datei zu" tail -f":

tail -c +0 -f /proc/PIDofProgram>/fd/# > /new/path/to/file

(dank der vorsichtigen Programmierer von tail funktioniert das sogar mit binärer Ausgabe.)

Während der Laufzeit hält das tail -f selbst die Datei offen und verhindert sicher, dass sie beim Beenden des ursprünglichen Programms von der Festplatte gelöscht wird. Stoppen Sie daher tail -f nicht unmittelbar nach dem Ende Ihres ursprünglichen Programms - überprüfen Sie die tail ' ed /new/path/to/file zuerst, ob es ist was Sie wollen. Wenn dies nicht der Fall ist (oder aus einem anderen Grund nicht zufriedenstellend ist), können Sie die Originaldatei erneut kopieren, aber diesmal nachdem das gesamte Schreiben von "Program" und aus dem noch laufenden Verzeichnis /proc/pidofail/fd/ beendet wurde.

 28
Author: Christian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/techietown.info/template/agent.layouts/content.php on line 61
2013-05-28 12:53:44

Verwenden Sie lsof, um die Inode-Nummer zu finden, und debugfs, um eine feste Verbindung zu ihr neu zu erstellen. Beispiel:

# lsof -p 12345 | grep /var/log/messages
syslogd 12345 root    3w   REG                8,3    3000    987654 /var/log/messages (deleted)
# mount | grep var
/dev/sda2 on /var type ext3 (rw)
# debugfs -w /dev/sda2
debugfs: cd log
debugfs: ln <987654> tmp
debugfs: mi tmp
                      Mode    [0100600] 
                   User ID    [0] 
                  Group ID    [0] 
                      Size    [3181271] 
             Creation time    [1375916400] 
         Modification time    [1375916322] 
               Access time    [1375939901]
             Deletion time    [9601027] 0
                Link count    [0] 1
               Block count    [6232] 
                File flags    [0x0] 
...snip...
debugfs:  q
# mv /var/log/tmp /var/log/messages
# ls -al /var/log/messages
-rw------- 0 root root 3301 Aug  8 10:10 /var/log/messages

Bevor Sie sich beschweren, habe ich das obige Transkript gefälscht, da ich gerade keine gelöschte Datei zur Hand habe; -)

Ich verwende mi, um die Löschzeit und die Anzahl der Links auf vernünftige Werte (0 bzw. 1) zurückzusetzen, aber es funktioniert nicht richtig - Sie können sehen,dass die Anzahl der Links in ls bei Null bleibt. Ich denke, der Kernel könnte die Inode-Daten zwischenspeichern. Sie sollten wahrscheinlich fsck an der früheste Gelegenheit nach der Verwendung von debugfs, auf der sicheren Seite zu sein.

Meiner Erfahrung nach sollten Sie den Link mit einem temporären Dateinamen erstellen und dann in den richtigen Namen umbenennen. Das direkte Verknüpfen mit dem ursprünglichen Dateinamen scheint zu einer Beschädigung des Verzeichnisses zu führen. YMMV!

 14
Author: Andrew Gallagher,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/techietown.info/template/agent.layouts/content.php on line 61
2013-08-08 10:24:14

Sie können einfach cp die Datei, dh:

cp /proc/<pid>/fd/<fdno> /new/path/to/file

Wenn die Datei noch geändert wird, werden Sie natürlich Probleme mit diesem Ansatz haben.

 4
Author: ninjalj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/techietown.info/template/agent.layouts/content.php on line 61
2011-05-13 23:55:29

Wenn Ihre Datei noch geschrieben wird (Sie können also cp nicht verwenden) und Sie ext nicht verwenden (Sie können also debugfs nicht verwenden), ist dies eine agnostische Methode.

Sobald Sie den Prozess mit ps aux | grep oder jedoch gefunden haben und den entfernten Dateinamen über lsof -p $pid -a -d $fd doppelt überprüft haben, können Sie den folgenden Spawn eines neuen Prozesses verwenden, dessen einzige Aufgabe es ist, ihn wiederzubeleben:

(tail -f -n +1 --pid $pid /proc/$pid/fd/$fd) >$file </dev/null 2>&1 &

Das seltsame Wrapping ist nur zum Schutz vor HUP, fühlen Sie sich also frei, es nicht zu benutzen oder gegen nohup

 0
Author: Hashbrown,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/techietown.info/template/agent.layouts/content.php on line 61
2020-08-27 04:23:25