如果已删除的文件仍被某个进程打开,该如何恢复?


19
$ 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)

如何恢复important_file呢?

我尝试了类似的东西

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

但它什么也没做。

Answers:


11

如果/ home是NFS,则/ home / vi中将存在一个.nfsNNNNNNNNNN文件,您可以访问/复制。如果home是本地文件系统,则应该可以通过/ proc / PID / fd / 3链接执行相同的操作:

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

如果您实际上要取消删除文件,请参阅有关此主题的博客文章


1
好的,我对readlink /proc/13381/fd/3->“ / home / vi / important_file(已删除)” 感到困惑,并且/home/vi/important_file\ \(deleted\)显然不存在。
六。

22

...比在给定时间复制(并仅收集该时间的文件内容快照)更好的方法是将该文件“ 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 /目录。


3
如何创建到/ proc / PIDofProgram> / fd /#的硬链接?
becko

2
@becko Invalid cross-device link
卡米尔Maciorowski

10

使用lsof查找索引节点号,并使用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

在您提出申诉之前,我没有提供要删除的文件,因此我伪造了上述成绩单;-)

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

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


如果它不能真正正常工作并导致系统损坏,那么您为什么要提出建议呢?我认为您应该在回答中提供更生动的免责声明,因为这仅仅是WiP,而不应在生产中真正试用。
cnst 2014年

3

您可以只是cp文件,即:

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

当然,如果仍在修改文件,则使用此方法会遇到麻烦。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.