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
AFAIK, find
searches the filesystem's directories. If that file was deleted but still existing because it's open (a common trick on unix), it won't be found by find
.
I haven't tried in Solaris, but here is a note about using lsof
to identify such 'deleted but open' files, and recovering via a cat /proc/<procid>/fd/<fdid> > /tmp/xxxx
Edit:
it seems you've already identified this is the case, but still wondering how is it possible. here's a short explanation:
on POSIX filesystem's, files are handled by its inode
, and the directories are little more than a "path => inode" mapping. You can have more than one path 'pointing' to the same inode (it's called a hardlink), and the inode keeps a count of how many links it has. The rm
command simply calls unlink()
on this path, which reduces the link count and 'possibly' deletes the file itself.
But a path on the directory tree isn't the only possible reference to an inode, an open fd
on a running process also counts, and a 'deleted' file won't be really removed until it goes to 0.
As i mentioned in passing above, it's a common trick: if you have a temporary file that you don't care to keep after your process finishes running, just open it and immediately 'delete' it. The opened handle will work reliably, and when your process finishes (either normally, killed or crashing), the system will remove the handle and cleanly delete the temporary file.
A logfile isn't a likely candidate for such a 'hidden autodeleting' file; but it's not hard to do accidentally.
Since your deleted logfile is still live and collecting data, it seems that simply copying the content wouldn't help much. so try creating a new hardlink to the /proc//fd/ file, something like ln /proc/4366/fd/1 /tmp/xxxx
. Note there's no -s
flag, so ln
should create a new hardlink with the same inode as the original, not a symbolic link (which is little more than a pointer to an existing path, and not what you want).
Edit:
The ln /proc/... /tmp/...
command can't work because /proc and /tmp are in different filesystems. Unfortunately, I don't know any way to create a pathname for an existing inode. One would want that the link()
syscall would take an inode number and a path, but it takes source and destination paths.
Best Answer
If the file is held open by another process then you can recover the file by using the inode number.
If the file not held open by another process then your out of luck with using the inode.