如果某些进程仍然打开已删除的文件,如何恢复?

Vi.*_*Vi. 25 linux file-recovery

$ 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)
Run Code Online (Sandbox Code Playgroud)

如何恢复important_file

我试过类似的东西

injcode -m dup2 -ofd=3 -ofilename=/tmp/recovered_file -oflags=O_CREAT $PID_OF_CAT
Run Code Online (Sandbox Code Playgroud)

但它什么也不做。

Chr*_*ian 30

...比在给定时间复制(并且只收集该时间的文件内容快照)更好的是将该文件“ tail -f”到一个新文件中:

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

(感谢 tail 谨慎的程序员,它甚至可以处理二进制输出。)

在运行期间,它tail -f本身保持文件打开,安全地防止在原始程序结束时将其从磁盘中清除。因此,不要tail -f在原始程序结束后立即停止-/new/path/to/file首先检查尾部是否您想要的。如果不是(或由于任何其他原因不满意),您可以再次复制原始文件,但这一次“程序”和仍在运行tail -f的 /proc/PIDoftail/ fd/ 目录。

  • 创建到 /proc/PIDofProgram>/fd/# 的硬链接怎么样? (4认同)
  • @becko `无效的跨设备链接`。 (3认同)

Mar*_*son 15

如果 /home 是 NFS,则 /home/vi 中将有一个 .nfsNNNNNNNNNN 文件,您可以访问/复制该文件。如果 home 是本地文件系统,您应该可以通过 /proc/PID/fd/3 链接做同样的事情:

cp /proc/PID/fd/3 /tmp/recovered_file
Run Code Online (Sandbox Code Playgroud)

如果您想真正取消删除文件,请参阅有关该主题的博客文章

  • 好吧,我被`readlink /proc/13381/fd/3` -> "/home/vi/important_file (deleted)" 和`/home/vi/important_file\\(deleted\)` 显然不存在弄糊涂了. (2认同)

小智 15

使用 lsof 查找 inode 编号,并使用 debugfs 重新创建指向它的硬链接。例如:

# 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
Run Code Online (Sandbox Code Playgroud)

在你抱怨之前,我伪造了上面的成绩单,因为我现在手头没有已删除的文件;-)

我曾经mi将删除时间和链接计数重置为合理的值(分别为 0 和 1),但它无法正常工作 - 您可以看到链接计数在ls. 我认为内核可能正在缓存 inode 数据。为了安全起见,您可能应该在使用 debugfs 后尽早 fsck。

根据我的经验,您应该使用临时文件名创建链接,然后重命名为正确的名称。将其直接链接到原始文件名似乎会导致目录损坏。天啊!