HowTo: Find Symlink under UNIX / Linux

by on September 3, 2010 · 25 comments· LAST UPDATED September 3, 2010

in

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

TwitterFacebookGoogle+PDF versionFound an error/typo on this page? Help us!

{ 25 comments… read them below or add one }

1 Bojan September 3, 2010 at 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

Reply

2 Philippe Petrinko September 4, 2010 at 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.

Reply

3 felix001 September 5, 2010 at 7:34 pm

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

Reply

4 Philippe Petrinko September 5, 2010 at 9:36 pm

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

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

don’t you think?

Reply

5 felix001 September 5, 2010 at 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 (??)

Reply

6 Philippe Petrinko September 5, 2010 at 10:01 pm

What do you get from:

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

Reply

7 Philippe Petrinko September 5, 2010 at 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…

Reply

8 TryThis September 5, 2010 at 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.

Reply

9 felix001 September 5, 2010 at 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

Reply

10 Philippe Petrinko September 5, 2010 at 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)

Reply

11 felix001 September 5, 2010 at 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

Reply

12 Philippe Petrinko September 5, 2010 at 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 ?

Reply

13 felix001 September 5, 2010 at 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

Reply

14 Philippe Petrinko September 5, 2010 at 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

Reply

15 Terryg September 6, 2010 at 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

Reply

16 Philippe Petrinko September 6, 2010 at 7:57 am

@Terry
Try (with sufficient rights):

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

is it OK?

Reply

17 Philippe Petrinko September 6, 2010 at 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)

Reply

18 Philippe Petrinko September 6, 2010 at 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)

Reply

19 Philippe Petrinko September 6, 2010 at 8:06 am

Terry,

There is also a builtin function in find:
Try:

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

What do you think?

Reply

20 Philippe Petrinko September 6, 2010 at 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

Reply

21 Philippe Petrinko September 6, 2010 at 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 ?

Reply

22 nixCraft September 6, 2010 at 2:31 pm

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

Reply

23 Philippe Petrinko September 6, 2010 at 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.

Reply

24 Terryg September 6, 2010 at 3:21 pm

Phillippe Petrinko,

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

Thanks,

Terry

Reply

25 Mohannad Otaibi September 11, 2010 at 4:34 am

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

Reply

Leave a Comment

Tagged as: , , , , , , , , , ,

Previous Faq:

Next Faq: