Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!wuarchive!brutus.cs.uiuc.edu!lll-winken!uunet!zephyr.ens.tek.com!tektronix!sequent!ccssrv!perry From: perry@ccssrv.UUCP (Perry Hutchison) Newsgroups: comp.unix.questions Subject: Re: Finding links Summary: It can be done, but it's slow Keywords: ln, ls, find Message-ID: <743@ccssrv.UUCP> Date: 20 Oct 89 01:02:28 GMT References: <598@cogent.UUCP> Reply-To: perry@ccssrv.UUCP (Perry Hutchison) Organization: Control-C Software, Inc., Beaverton, OR Lines: 50 In article <598@cogent.UUCP> doug@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.