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.
This is written in Bash and uses features specific to it (but similar features are available in other shells). It's designed to be run from a parent directory common to all the files and directories you're interested in. It takes into account the length of the path from /
to there and adds it to the length of each evaluated path. If you don't want to do that just use lenpwd=0
instead of lenpwd=${#PWD}
. It will work if there are files with spaces in their names but not those that have newlines (which should be banished any way). It prints the lengths and filespec of anything it finds that meet the criteria.
lenpwd=${#PWD}; find | while read -r path; do file=${path##*/}; if (( ${#path} + lenpwd > 1024 || ${#file} > 256 )); then echo "$((${#path} + lenpwd)) ${#file} $path"; fi; done
Best Answer
The ino value is the inode of the file on the filesystem, in your case 13621 so you could use
find
's -inum option like so (where $filesystem_name is a filesystem on your machine:Inodes are unique per filesystem, so if you have multiple filesystems you might want to check them individually.
There are some nice dtrace scripts on the web for finding activity on filesystems:
http://forums.sun.com/thread.jspa?threadID=5075136