≡ Menu

HowTo: Find Symlink under UNIX / Linux

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

Tweet itFacebook itGoogle+ itPDF itFound an error/typo on this page?

{ 25 comments… add one }

  • Bojan September 3, 2010, 3:56 pm

    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

    • Philippe Petrinko September 4, 2010, 11:36 am

      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.

  • felix001 September 5, 2010, 7:34 pm

    How would you use the find command to find which links are assiociated with the /etc/init.d/network files ?

    • Philippe Petrinko September 5, 2010, 9:36 pm

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

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

      don’t you think?

      • felix001 September 5, 2010, 9:42 pm

        Not really as it doesnt seem to work :

        [root@server /]# ls -lia /etc/rc3.d/S10network
        197009 lrwxrwxrwx 1 root root 17 Jun 20 09:36 /etc/rc3.d/S10network -> ../init.d/network
        [root@server /]# 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 (??)

        • Philippe Petrinko September 5, 2010, 10:01 pm

          What do you get from:

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

          • Philippe Petrinko September 5, 2010, 10:10 pm

            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…

        • TryThis September 5, 2010, 10:01 pm

          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.

  • felix001 September 5, 2010, 10:19 pm

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

    [root@server /]# 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
    [root@server /]# 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
    [root@server /]# ls -l /etc/rc3.d/*network*
    lrwxrwxrwx 1 root root 17 Jun 20 09:36 /etc/rc3.d/S10network -> ../init.d/network

    • Philippe Petrinko September 5, 2010, 10:31 pm

      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)

      • felix001 September 5, 2010, 10:42 pm

        The results from that were
        [root@Fileserver /]# 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

        [root@Fileserver /]# 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

        • Philippe Petrinko September 5, 2010, 10:56 pm

          [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 ?

  • felix001 September 5, 2010, 10:58 pm

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

  • Philippe Petrinko September 5, 2010, 11:53 pm

    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

  • Terryg September 6, 2010, 2:42 am

    But is there a way to just find symlinks w/o specifying a file name. Like dangling symlinks and such?

    Thanks,

    Terry

    • Philippe Petrinko September 6, 2010, 7:57 am

      @Terry
      Try (with sufficient rights):

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

      is it OK?

      • Philippe Petrinko September 6, 2010, 7:59 am

        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)

        • Philippe Petrinko September 6, 2010, 8:00 am

          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)

    • Philippe Petrinko September 6, 2010, 8:06 am

      Terry,

      There is also a builtin function in find:
      Try:

      find -L / -type l -lname "*"

      What do you think?

      • Philippe Petrinko September 6, 2010, 8:13 am

        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

  • Philippe Petrinko September 6, 2010, 8:23 am

    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 ?

    • nixCraft September 6, 2010, 2:31 pm

      I will create new find command topic and I appreciate all your comments and effort.

  • Philippe Petrinko September 6, 2010, 8:28 am

    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.

  • Terryg September 6, 2010, 3:21 pm

    Phillippe Petrinko,

    I was just curious as how to find a dead symlink.

    Thanks,

    Terry

  • Mohannad Otaibi September 11, 2010, 4:34 am

    Wouldn’t be better to use:
    find / -type l

Leave a Comment