14

I have a file that was deleted, but is still held open by a program. I found the inode number using lsof. How can I create a hard link back to that inode?

Dennis Williamson
  • 60,515
  • 14
  • 113
  • 148
Jeff Ferland
  • 20,239
  • 2
  • 61
  • 85

3 Answers3

31

You can't create a link to it, but you can get it back. Let's do an experiment:

$ echo blurfl >myfile.txt
$ tail -f myfile.txt &
$ rm myfile.txt

myfile.txt is now gone, but the inode is kept alive by the tail command. To get your file back, first find the PID of the process keeping the inode:

$ ps auxw | grep tail
sunny      409  0.0  0.0   8532   824 pts/5    S    18:07   0:00 tail -f myfile.txt

The PID is 409. chdir to /proc/409/fd/ and list the contents:

dr-x------ 2 sunny sunny  0 2009-07-24 18:07:18 .
dr-xr-xr-x 7 sunny sunny  0 2009-07-24 18:07:17 ..
lrwx------ 1 sunny sunny 64 2009-07-24 18:07:33 0 -> /dev/pts/5
lrwx------ 1 sunny sunny 64 2009-07-24 18:07:33 1 -> /dev/pts/5
lrwx------ 1 sunny sunny 64 2009-07-24 18:07:18 2 -> /dev/pts/5
lr-x------ 1 sunny sunny 64 2009-07-24 18:07:33 3 -> /home/sunny/tmp/myfile.txt (deleted)

The /proc/[PID]/fd/ directories contain symlinks to file descriptors of all files the process uses. In this case the symlink "3" points to the deleted file. So, to restore the file, copy the contents to a new file:

$ cat 3 >/home/mydir/saved_file.txt
sunny256
  • 861
  • 7
  • 8
  • I've done this with a filesystem debugger in the distant past (e.g. "debugfs dump"), but the concept is the same. – Gerald Combs Jul 24 '09 at 16:32
  • 1
    nice answer, +1 – asdmin Jul 24 '09 at 17:54
  • This doesn't work for me. Given that '3' is a dangling symlink, not a "real" file descriptor, it always just creates an empty file. – Rob Chanter Aug 17 '09 at 02:53
  • 4
    @Rob: No, it doesn't. If the file descriptor is in use, the symlink points to valid data, otherwise the symlink wouldn't exist in the first place. When the file is closed, the symlink disappears. You did have a space after the "3", right? If not, you'll output the contents of file descriptor 3 in the current shell instead, and _that's_ probably empty. – sunny256 Aug 30 '09 at 05:59
  • 1
    The only problem with this is that if the file is still being written to then the copy you make will be truncated. There's probably no time between when the write stops and the file is closed to do this so that you get a complete file. – KayEss Jun 03 '13 at 06:14
  • you may as well use `ln` to create a hardlink instead of copy. It is possible only when your hardlink location is on the same FS as original file. No data will be physically moved/copied, it's just another name for same file. – DukeLion Oct 28 '13 at 04:44
2

to get the whole file if it is still written to try tail -c +1 -f

from: https://unix.stackexchange.com/questions/25527/how-to-follow-a-la-tail-f-a-binary-file-from-the-beginning

(btw: ln from the fd on /proc doesn't work, just tried that)

eMBee
  • 21
  • 2
-8

There is no portable way to do this under Linux. Best way would probably be to get all activity on the file-system to cease, kill the program that holds the file open, unmount the file system and use a file-system debugger to re-attach it to a directory. If you have the file system exported through NFS, at least some versions of NFS may allow you to read the file data across NFS.

Vatine
  • 5,390
  • 23
  • 24