Finding links

Perry Hutchison perry at ccssrv.UUCP
Fri Oct 20 11:02:28 AEST 1989


In article <598 at cogent.UUCP> doug at cogent.UUCP (Doug Perlich) asks how to
find the other (link) names by which a file is known.

Many UNIX versions ago, there were a couple of programs called icheck and
ncheck which could help with this sort of thing.  They read the disk directly,
bypassing the file system.  They could be pretty slow if the disk was very
large.  (Their primary function, filesystem consistency checking and repair,
has since been taken over by fsck.)

The problem is that the file's inode contains the number of links which the
file has (this is the number which ls displays just ahead of the owner's
name), but it has no record of the links themselves.  In order to find the
file's other names, you have to determine its inode number and then search
every directory on the disk for other entries which point to that same inode.
(Unless you're looking for inconsistencies, you can stop as soon as the
number of links found equals the inode's link-count value.)

If you really need to do this, you can use 
  ls -i
to get the inode number, and then
  find volroot -xdev -inum #### -print
to scan the disk's directory tree and print the other names.

In the above, "volroot" refers to the directory on which the particular
filesystem's root directory is mounted and "####" is to be replaced by the
inode number obtained from ls -i.  On my system (SunOS, a BSD derivative),
-xdev tells find not to look at any filesystems which may be mounted within
the tree being scanned.  Check your man-page, as your mileage may vary, and
be aware that this technique will not find any links which may be located
in directories to which you don't have read permission.

[Flame-shield: Yes I know this can be reduced to a one-liner by piping the
result of ls through sed or cut, and including the result into the find
with ``.  I'm trying to keep it readable.  end of flame-shield]

So far, I've been assuming that you're only interested in "hard" links.  If
you need to find symbolic links also, another step is required:

  find / -type l -ls | fgrep -f linklist

where linklist is the file in which you've saved the list of names from the
previous find operation.  What this second find is doing is searching the
entire system for symbolic links (which, unlike hard links, need not be on
tha same filesystem with their target), doing the equivalent of an
"ls -gilds" on each, and then using fgrep to select from that list only
those entries which match one of the file's real names.

If the file has only one real name, it would be better to use grep so that
the match can be restricted to the end of the line.  It may be possible to
handle the multiple-name case, including end-of-line restriction, with egrep.



More information about the Comp.unix.questions mailing list