HowTo: Find Symlink under UNIX / Linux

Posted on in Categories , last updated September 3, 2010

How do I find symlink(s) under UNIX and Linux operating systems?

To find all symlinks to /etc/resolv.conf, use the find command as follows:
# find /path/to/dir -lname /path/to/file
# find / -lname /etc/resolv.conf

/path/to/file is a symbolic link whose contents match shell pattern pattern. The metacharacters do not treat / or . specially. The -ilname FILE options is like -lname, but the match is case insensitive:
# find / -ilname resolv.conf

25 comment

  1. Hello Vivek,

    I follow your site daily, and I can say that I am impressed with its contents, they are excellent!
    However, I tried to apply your command above: find / -lname /etc/resolv.conf, but without any sucess. Right now, I`m writing a Perl script to return me the hard-link if a symlink exists. For example, I tried this:

    if (-l $searchString)
    {
    readlink -f $searchString;
    }

    I might be wrong, but this should be applied with a regex on all files, later I search all files for a specific string, and I want to search a symlink that points to a hardlink of the real file and grep its contents too. Is that possible and how, could the command above work somehow too?

    Thanks in advance, Bojan

    1. Hello, useful topic Vivek, thanks

      May be the second example should contain a globbing metacharacter to illustrate your words.

      find . -lname *resolv.conf

      @Bojan: sorry but it works fine.
      Try this

      mkdir -p ~/dir1/dir2
      ln -s /etc/resolv.conf ~/dir1/dir2/mysoftlink
      
      find ~ -lname /etc/resolv.conf
      /home/me/dir1/dir2/mysoftlink
      
      find ~ -lname *resolv.conf
      /home/me/dir1/dir2/mysoftlink
      

      It works fine.

    1. @Felix
      It seems to be clear following Vivek’s instruction…

      # find / -lname /etc/init.d/network

      don’t you think?

      1. Not really as it doesnt seem to work :

        [[email protected] /]# ls -lia /etc/rc3.d/S10network
        197009 lrwxrwxrwx 1 root root 17 Jun 20 09:36 /etc/rc3.d/S10network -> ../init.d/network
        [[email protected] /]# find /etc -lname /etc/init.d/network

        As you can see the file is there but no results are being returned from the find command (??)

          1. Actually,

            This would be enough:

            find /etc -lname */init.d/network

            The trick here is that the link is not absolute but relative.
            It links to the upper directory (it start with ../ )

            So, in case of relative links, I must admit that it may be somewhat more difficult than for absolute links ! :-)
            I don’t know if there is another trick to solve this…

        1. From the man page:

          File is a symbolic link whose contents match shell pattern pattern. The metacharacters do not treat ‘/’ or ‘.’ specially.

          So here we go:
          find /etc -lname *network*
          /etc/rc.d/rc3.d/S10network
          /etc/rc.d/rc6.d/K90network
          /etc/rc.d/rc5.d/S10network
          /etc/rc.d/rc1.d/K90network
          /etc/rc.d/rc2.d/S10network
          /etc/rc.d/rc0.d/K90network
          /etc/rc.d/rc4.d/S10network

          May be -lname changes according to UNIX or Linux version, see your local find command man page.

  2. OK thats kinda of helped but how come when i do this search i only get the sym links from the rc.d directory ?

    [[email protected] /]# find /etc -lname *network*
    /etc/rc.d/rc4.d/S10network
    /etc/rc.d/rc5.d/S10network
    /etc/rc.d/rc6.d/K90network
    /etc/rc.d/rc1.d/K90network
    /etc/rc.d/rc3.d/S10network
    /etc/rc.d/rc0.d/K90network
    /etc/rc.d/rc2.d/S10network
    [[email protected] /]# ls -l /etc/rc.d/rc3.d/*network*
    lrwxrwxrwx 1 root root 17 Jun 20 09:36 /etc/rc.d/rc3.d/S10network -> ../init.d/network
    [[email protected] /]# ls -l /etc/rc3.d/*network*
    lrwxrwxrwx 1 root root 17 Jun 20 09:36 /etc/rc3.d/S10network -> ../init.d/network

    1. 1) What are results from

      find /etc -lname */init.d/network

      2) Well, that’s kind of weird. Are you sure that
      /etc/rc.d/rc3.d/
      and
      /etc/rc3.d
      are real directories, and not links?

      (on my Debian, I do not see any /etc/rc.d)

      1. The results from that were
        [[email protected] /]# find /etc -lname */init.d/network
        But I would of thought from `find /etc -lname *network` I would of got both linkss from /etc/rc3.d/S10network and also from /etc/rc.d/rc3,d/S10network

        [[email protected] /]# ls -ld /etc/rc*.d
        lrwxrwxrwx 1 root root 10 Jun 20 09:36 /etc/rc0.d -> rc.d/rc0.d
        lrwxrwxrwx 1 root root 10 Jun 20 09:36 /etc/rc1.d -> rc.d/rc1.d
        lrwxrwxrwx 1 root root 10 Jun 20 09:36 /etc/rc2.d -> rc.d/rc2.d
        lrwxrwxrwx 1 root root 10 Jun 20 09:36 /etc/rc3.d -> rc.d/rc3.d
        lrwxrwxrwx 1 root root 10 Jun 20 09:36 /etc/rc4.d -> rc.d/rc4.d
        lrwxrwxrwx 1 root root 10 Jun 20 09:36 /etc/rc5.d -> rc.d/rc5.d
        lrwxrwxrwx 1 root root 10 Jun 20 09:36 /etc/rc6.d -> rc.d/rc6.d
        drwxr-xr-x 10 root root 4096 Jun 20 09:36 /etc/rc.d

        1. [You didn’t tell us you distribution name – just for information]

          As a matter of fact, there is only ONE link, in only ONE real directory:
          /etc/rc.d/rcX.d/S10network -> ../init.d/network
          (please note that X stands for 0, 1, 2, 3, 4, 5, 6 here)

          Indeed,
          /etc/rcX.d/S10network
          is actually linked to
          /etc/rc.d/rcX.d/S10network

          through the link
          /etc/rc3.d -> rc.d/rc3.d

          Is it clear now ?

  3. Not really as /etc/rc3.d/S10network is linked to /etc/init.d/network
    [[email protected] /]# ls -lai /etc/rc3.d/S10network
    197009 lrwxrwxrwx 1 root root 17 Jun 20 09:36 /etc/rc3.d/S10network -> ../init.d/network

  4. OK – you don’t get one thing:
    Figure out one first link, a directory link to a target directory
    Figure out a second link, a file link to a target file.

    Target File seems to belong to 2 directories, the real one, and the link directory.

    If you still do not get it, try this:
    First, do no login as root, try any user with no admin rights (that will prevent you from making big mistakes)

    1) OK, so go in your home directory.

    cd

    2) create real directories:

    mkdir -p etc/rc.d/rc{0..6}.d

    3) create real target file

    touch ~/vivek-fan

    4) create directory links

    for x in {0..6}; do ln -sT "rc.d/rc${x}.d" "etc/rc${x}.d";done

    5) create only one file link for test

    ln -s ~/vivek-fan ~/etc/rc.d/rc0.d/

    6) check

    ls -lai ~/etc/rc0.d/vivek-fan
    1130526 lrwxrwxrwx 1 me users 23 sep 6 01:46 /home/me/etc/rc0.d/vivek-fan -> /home/me/vivek-fan

    7) Now try to find the link:


    find ~/etc -lname "*/vivek-fan"
    /home/me/etc/rc.d/rc0.d/vivek-fan

    See? only one link

    1. @Terry
      Try (with sufficient rights):

      find . -type l | (while read; do test -e "$REPLY" || ls -ld "$REPLY"; done)

      is it OK?

      1. Of course, to find in the whole directory tree, use “/” instead of current directory( if working directory is not “/” )


        find . -type l | (while read; do test -e "$REPLY" || ls -ld "$REPLY"; done)

        1. ooops – I meant

          Of course to find in the whole directory tree, use “/” instead of current directory if working directory is not “/”

          find / -type l | (while read; do test -e "$REPLY" || ls -ld "$REPLY"; done)

          (Vivek please delete my previous post please)

      1. One more:
        this one will list broken link

        find -L /home -type l

        this one will list broken link and their target (option -ls)

        find -L /home -type l -ls

  5. I my humble opinion, Vivek could make another specific topic or a specific chapter in this topic to cover all aspects of finding broken links.
    For instance, one must prevent searching [ /dev ] directory which normally contains lots of broken links, and there are several tricks to avoid searching [ /dev ].
    What do you think, Vivek ?

  6. anyone will find interesting material just entering

    man symlink

    It seems to exists a add-on command, [ symlinks ], which deals good with the matter.
    Not tested it yet.

Leave a Comment