Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I read "most" of the proposed questions, but I believe they all miss the complexity of the right answer.

I want, only using "basic" commands (for maximum portability) (i.e., something that would work on AIX / Linux / etc., not just something using a recent nicety ^^), to find all the files (symlinks, hardlinks and combinations thereof) pointing to a specific file/dir.

Be careful to not rush to answer find / -ls | grep .... : it will miss many cases. See my links below, mixing hardlinks, symlinks, relative-and-absolute paths (and also play with symlinks "././././." possibilities)

ie

  • hardlinks and symlinks can be "nested", ad-inifinitum...
  • some symlinks could be with the full path, others with a relative path,
  • those paths (relative or absolute) could be very complex (ex: /tmp/././../etc/file )
  • a symlink could lead to a file, which hardlink to another, which is a symlink to a third, which ends up [after some more iteration] to the final destination...

In the end, I "just" need to find out a way to know what is the "final destination" of any file/link (ie, which inode will be accessed in the end?). But it's really tough (unless some magical function will tell me "the final destination inode is : ...". That's what I need!)

I thought I could simply use '-H' or '-L' options of find, but (I'm probably dumb...) it didn't work... yet.

Any info welcomed (but please, using find/ls/etc, not some "nice utility only available on linux")

Try to create some different links to the "/tmp/A" directory, and find a way to find and list them all:

mkdir /tmp/A    /tmp/B
ln -s /tmp/A/   /tmp/B/D  #absolute symlink, with a training "/"
ln -s ../A      /tmp/B/E     #relative symlink
ln -s /tmp/A/.  /home/F  #absolute symlink, with a trailing "/."
ln -s ../tmp/A/./.  /var/L  #let's get craaaaaaazy! symlinks are "fun"...
ln    /tmp/B/D  /etc/G    #Hard-link to the symlink file /tmp/B/D, which itself symlink to /tmp/A/ witch ends up being the same as "/tmp/A" in most cases.
ln    /etc/G    /etc/G2   #and a duplicate of the previous one, just to be sure [so /etc/G, /etc/G2, and /tmp/B/D have same inode, but it's a different inode from the final destination... :(
ln -s etc/G /thatsenough   #symlink again, for further chaining

and then some tries:

find -H / -ls   # show inodes of the links and symlinks, not of the "final" directory
find -L / -ls   # same thing (I do try that on an OLD AIX ...)
find -H / -inum 123456 -ls  #if /tmp/A/. has inode 123456. This lists *only* hardlinks to /tmp/A, ie will only print a subset (and /tmp/A have to be a file in that case)

I expected to see the final inode (123456) in front of all the paths, in one of those invocation (I also added '-follow' to both), but I always see the inodes of the links, not of the "final destination" (i.e., /tmp/A)

What could I use to find out the "final inode" I end up accessing? [the OS manages it, but can a "simple" command tell me beforehand "through that file, you will open that final inode!"?]

share|improve this question
    
to be thorough: if you can add files in the "final destination dir" or edit "the final destination file", it's possible: create a very_specific_filename inside that dir, and for i in $(find / -print) ; do [ -f $i/very_specific_filename ] ; done (for a dir), or ... do grep "specific_string" "$i" ... (for a file). This works, and is easy. But for this you need to edit the destination file/dir. I want a solution where you can NOT change/edit the destination file/dir [ex for forensics: I want to find all, even well hidden, links to a file or dir, and can't afford to change them for that] –  Olivier Dulac Nov 7 '13 at 18:39
3  
find / -exec ls -iLd {} | grep inodenum . There are always going to be cases you can't catch, such as a symlink that points to a symlink on a file system that's only occasionally mounted and whose contents are not under your control. –  Mark Plotnick Nov 7 '13 at 18:52
    
@MarkPlotnick: +1. I'm sorry I didn't try out your solution [I was thinking that it would only show up the link's inode instead of the destination's one... But it does work! At least for directories! (and now my workaround looks silly ^^). I'll now see if it works for the convulated cases I pointed above [i just tested on a very smaller subset of special cases] –  Olivier Dulac Nov 8 '13 at 9:35
    
@MarkPlotnick: it's indeed what I was looking for ! follows any combination of hard-links&symlinks up to the final destination and print that final destination's inode! Please post it as an answer, so I can give its due credit! –  Olivier Dulac Nov 8 '13 at 9:50

3 Answers 3

up vote 1 down vote accepted

ls has a -L option that will effectively chase symlinks and show the perms, owner, inode, etc. of the ultimate object. [It does this by doing stat(target) instead of lstat(target)]. For best results, run as root or as someone who has read access to relevant mounted filesystems.

So in your case, try the following:

find / -exec ls -iLd {} | grep inodenum

[copied from my comment, per request of the OP.]

share|improve this answer
    
thanks, +1 (actually -L didn't work for me with "find", but your version using it in "ls" instead of "find" does work!) –  Olivier Dulac Nov 8 '13 at 23:17
1  
Thanks, I indeed meant to say ls. Answer fixed. –  Mark Plotnick Nov 9 '13 at 2:50

The question is not uniformly answerable. For example, by chaining just a few symlinks in a tree, I can create infinitely many possible paths that resolve to the same inode.

Your desire for complete portability is also unlikely to succeed. For example, even "find" differs in the wild between GNU, BSD, POSIX and other variants (and of course between versions of those variants).

But what you want may be something akin to find / -samefile /absolute/path/to/file.

This is available in GNU find >= 4.2.11.

share|improve this answer
    
Consider setting a reasonably high -maxdepth to avoid inifinite recursion if necessary. –  Joe Atzberger Nov 7 '13 at 21:57
    
find -samefile isn't enough: it doesn't follow symbolic links. Adding -L would follow symlinks, but then find would also recurse into symlinks to directories, which is not desirable here. –  Gilles Nov 7 '13 at 22:38
    
thanks for the answer, but I hope someone knows about a "magic" command that will be able to tell "This inodeX hardlink/symlink is linked to inodeY+inodeZ... files [including those files reached by following several 'hops', and avoiding loops...]". Actually I have a nice workaround when the destdir is a directory, but not when it's not a directory. I'll post it. –  Olivier Dulac Nov 8 '13 at 9:10

update: Mark Plottnick's answer (under my question) was much simpler and works for files & directories, and gives the final destination's inode following any combination of links in-between !
It was what I was looking for [unless I forgot special cases in my test directory].
I'm glad the final solution is so elegant and portable! Mark, please post it so that I can give you the checkmark ^^

I let my own workaround below, which now looks very silly ^^

===

I found some incredibly easy workaround when the destination file is a directory! Just add a "/." after its name, and you'll have the final destination's directory inode! And you'll still print the originating path!

find / -print | xargs -n 1 ls -ild '{}'/. 2>/dev/null | grep inodeyouwant

note: it's very heavy in "try to do this on a file without knowing if it's a symlink or hardlink at all", so I'll update with one that only look for hard-links+symlinks.

But now I need to figure out a way to do this for "not-leading-to-a-directory-in-the-end" file[s] (ie, links/symlinks/chain-of-those that in the end point to something that is not a directory) (once again, without modifying that final destination!)

I'll update when I found a nice way for that

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.