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

🐧 If you liked this page, please support my work on Patreon or with a donation.
🐧 Get the latest tutorials on SysAdmin, Linux/Unix, Open Source/DevOps topics:
CategoryList of Unix and Linux commands
File Managementcat
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network Utilitiesdig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04
25 comments… add one
  • Bojan Sep 3, 2010 @ 15:56

    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 Sep 4, 2010 @ 11:36

      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 Sep 5, 2010 @ 19:34

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

    • Philippe Petrinko Sep 5, 2010 @ 21:36

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

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

      don’t you think?

      • felix001 Sep 5, 2010 @ 21:42

        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 Sep 5, 2010 @ 22:01

          What do you get from:

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

          • Philippe Petrinko Sep 5, 2010 @ 22:10

            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 Sep 5, 2010 @ 22:01

          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 Sep 5, 2010 @ 22:19

    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 Sep 5, 2010 @ 22:31

      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 Sep 5, 2010 @ 22:42

        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 Sep 5, 2010 @ 22:56

          [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 Sep 5, 2010 @ 22:58

    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 Sep 5, 2010 @ 23:53

    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 Sep 6, 2010 @ 2:42

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

    Thanks,

    Terry

    • Philippe Petrinko Sep 6, 2010 @ 7:57

      @Terry
      Try (with sufficient rights):

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

      is it OK?

      • Philippe Petrinko Sep 6, 2010 @ 7:59

        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 Sep 6, 2010 @ 8:00

          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 Sep 6, 2010 @ 8:06

      Terry,

      There is also a builtin function in find:
      Try:

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

      What do you think?

      • Philippe Petrinko Sep 6, 2010 @ 8:13

        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 Sep 6, 2010 @ 8:23

    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 Sep 6, 2010 @ 14:31

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

  • Philippe Petrinko Sep 6, 2010 @ 8:28

    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 Sep 6, 2010 @ 15:21

    Phillippe Petrinko,

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

    Thanks,

    Terry

  • Mohannad Otaibi Sep 11, 2010 @ 4:34

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

Leave a Reply

Your email address will not be published. Required fields are marked *

Use HTML <pre>...</pre>, <code>...</code> and <kbd>...</kbd> for code samples.