Operating System - HP-UX
1834771 Members
3099 Online
110070 Solutions
New Discussion

Re: resolving the source of a link

 
Alan Hatch
Advisor

resolving the source of a link

Hi folks,

I'm being told that this is impossible, but I thought that I would ask.

I need to find the source of a soft link when I know the target.

Is there any way to do this other than find commands (I need to resolve thousands of links across terabytes of data)?


Thanks.

Alan
13 REPLIES 13
RAC_1
Honored Contributor

Re: resolving the source of a link

ll "soft_link" | awk '{print $10, $12}'

First is soft link and 2nd the source

Anil
There is no substitute to HARDWORK
Alan Hatch
Advisor

Re: resolving the source of a link

I don't have the link, only the target.

Thanks.

Alan
Geoff Wild
Honored Contributor

Re: resolving the source of a link

Good question....

I don't think that information is kept anywhere - not in an inode, or stat.......etc...

You have a directory (or file) and want to know if there are any symbolic (or hard) links to it.

Rgds...Geoff
Proverbs 3:5,6 Trust in the Lord with all your heart and lean not on your own understanding; in all your ways acknowledge him, and he will make all your paths straight.
RAC_1
Honored Contributor

Re: resolving the source of a link

man ls
ls -L file

If it has links, it will display source file and not the link.

Anil
There is no substitute to HARDWORK
Geoff Wild
Honored Contributor

Re: resolving the source of a link

Anil - ls -L

If the argument is a symbolic link, list the file or
directory to which the link refers rather than the link
itself.

What Alan want, is a list of all symblic links pointing to a particular directory.

Example:

/oracle is a mount point and a directory.

What (if any) symbolic links out on the system are pointing to it?

Rgds...Geoff
Proverbs 3:5,6 Trust in the Lord with all your heart and lean not on your own understanding; in all your ways acknowledge him, and he will make all your paths straight.
Sundar_7
Honored Contributor

Re: resolving the source of a link

hmm..guess the way "source" and "target" is used is confusing to the folks

Say SOFTLINK is linked to FILE then

# ls -l SOFTLINK

will tell which file it is linked to

but there is no way to trace SOFTLINK from FILE except ofcourse by using find.



Learn What to do ,How to do and more importantly When to do ?
Patrick Wallek
Honored Contributor

Re: resolving the source of a link

Nope, that still isn't what he wants RAC.

Say you have the following:

# ll test
lrwxr-xr-x 1 root sys 16 Sep 2 15:47 test@ -> security_catalog

He wants to be able to run a command on the file security_catalog and determine that test links to security_catalog.

I agree with the other folks above, I don't think this is easily doable. The only thing I can really think of is 'find /dir -type l -exec ll -d {} \;'

Jeff Schussele
Honored Contributor

Re: resolving the source of a link

Hi Alan,

How about using find?

find /start_point -type l -exec ls -l {} \; | grep "/full/path/to/target"

Note - this may put a hammer on the system whilst it runs. But it should work

Rgds,
Jeff
PERSEVERANCE -- Remember, whatever does not kill you only makes you stronger!
RAC_1
Honored Contributor

Re: resolving the source of a link

On the basis on Jeff's reply, instead of running find you can use tllist|grep "target"

But tllist lists only the transitional links.

Anil
There is no substitute to HARDWORK
Patrick Wallek
Honored Contributor

Re: resolving the source of a link

I just whipped up the following script. It's not elegant, but it appears to work. I think.

No guarantees. Your mileage may vary. Etc, etc.

I used the /etc directory as my test case. Modify it to fit your needs.

#!/usr/bin/sh

find /etc -type l | xargs ll | awk '{print $11,$9}' > /home/root/link_list

cat /home/root/link_list | sort > /home/root/link_list1

while read ORIGFILE LINK

do
if [ "${FILE}" != "${ORIGFILE}" ] ; then
echo ""
echo ""
echo "${ORIGFILE} has the following links pointing to it: "
echo "${LINK}"
else
echo "${LINK}"
fi
FILE=${ORIGFILE}
done < /home/root/link_list1
Alan Hatch
Advisor

Re: resolving the source of a link

Thanks for all of your help.

I'm running find commands now to build a list of the regular files.

Unfortunately, I will have to resolve the information I need via a ctree database, so it will be slow going.

Thanks again.

Alan
Hein van den Heuvel
Honored Contributor

Re: resolving the source of a link

Hmm,

May we assume you have fewer links then actual files?

Why would you want a (large) list of all real files if all you seem to want is the real files which are being pointed to?

Anyway... it does not seem to be a trival problem. I could not find a 'handy' command to really follow a link down to a path.
Sure, 'ls -l' and the readlink function will show the softlink, but that may well be relative! Like: ../../xxx/yyy/realfile.dat

There is some shell code to do this, for example see:
http://www.kaffe.org/pipermail/kaffe/1998-September/086554.html

But what I liked best was a perl solution as per:

http://www.stonehenge.com/merlyn/UnixReview/col27.html

I'll attach the working code for that.
I _think_ it solves your problem if you use it with for example:

find /etc -type l -exec perl follow.p {} \; | sort -k 3 > links.lst

Then you can grep the resulting links.lst for the real file names.

It is NOT fast.
If I needed this, then I would probably modify it to an all perl, single activation, solution using 'glob' and the '-l' test.

Sample output below, followed by code (also attached).
Hope this helps...

Hein.

/etc/snmpd.conf is /etc/SnmpAgent.d/snmpd.conf
/etc/checklist is /etc/fstab
/etc/aliases is /etc/mail/aliases
/etc/dce_com_env is /etc/opt/dce/dce_com_env
/etc/dce_com_utils is /etc/opt/dce/dce_com_utils
/etc/dce_config_env is /etc/opt/dce/dce_config_env
/etc/dce_config_utils is /etc/opt/dce/dce_config_utils
/etc/opt/gnome/gtk/gtkrc.be is /etc/opt/gnome/gtk/gtkrc.cp1251
/etc/opt/gnome/gtk/gtkrc.bg is /etc/opt/gnome/gtk/gtkrc.cp1251
/etc/opt/gnome/gtk/gtkrc.he_IL.cp1255 is /etc/opt/gnome/gtk/gtkrc.cp1255
/etc/opt/gnome/gtk/gtkrc.he_IL.microsoftcp1255 is /etc/opt/gnome/gtk/gtkrc.cp1255
/etc/opt/gnome/gtk/gtkrc.yi is /etc/opt/gnome/gtk/gtkrc.cp1255
/etc/opt/gnome/gtk/gtkrc.lt is /etc/opt/gnome/gtk/gtkrc.iso-8859-13
/etc/opt/gnome/gtk/gtkrc.lv is /etc/opt/gnome/gtk/gtkrc.iso-8859-13
/etc/opt/gnome/gtk/gtkrc.mi is /etc/opt/gnome/gtk/gtkrc.iso-8859-13
/etc/opt/gnome/gtk/gtkrc.cy is /etc/opt/gnome/gtk/gtkrc.iso-8859-14
/etc/opt/gnome/gtk/gtkrc.ga is /etc/opt/gnome/gtk/gtkrc.iso-8859-14
:

use File::Find;
use Cwd;
find sub {
my $dir = cwd;

exit 1 unless -l;
my @right = split /\//, $File::Find::name;
my @left = do {
@right && ($right[0] eq "") ?
shift @right : # quick way
split /\//, $dir;
}; # first element always null
while (@right) {
my $item = shift @right;
next if $item eq "." or $item eq "";
if ($item eq "..") {
pop @left if @left > 1;
next;
}
my $link = readlink (join "/", @left, $item);
if (defined $link) {
my @parts = split /\//, $link;
if (@parts && ($parts[0] eq "")) { # absolute
@left = shift @parts; # quick way
}
unshift @right, @parts;
next;
} else {
push @left, $item;
next;
}
}
print "$File::Find::name is ", join("/", @left), "\n";
}, @ARGV;



Steve Post
Trusted Contributor

Re: resolving the source of a link

You have file A.
You have file B,C,.. that points to file A.

1. Find all files that are links.
2. Run ls -ld on each file.
(find / -type l -print | xargs ls -ld > big.txt)

3. Use the resultant output (i.e. big.txt) to make a perl hash. The key is the fake, link file. The value is the real file that the link is pointing too.

You can't do this on the fly during the day. You have lots of stuff running. This could take hours. So find all the links via a cronjob in the middle of the night.

Ok you ran it once. Now run it each night for just the changes in the last 24 hours.
find / -type l -mtime -1 -print | xargs ls -ld >> bigchanges.txt

Now as far as the details in coding? I'd listen to the other folks here. I'm just trying to tell you there IS a way to get what you want. It would just take some planning to process through terabytes of filesystem.

Oh and be careful to the size of the results. You would not want your big report to exceed the size of the filesystem it sits
on in the middle of the night.

Ok one more SILLY note. One time I had a simple command like "tail -20 bigfile" FAIL because of kernel limits in passing through the pipe command. There are limits to the number of arguments allowed for xargs. There are limits to the length of an arguments. This happened to me a number of years ago. But it was like using physics when approaching the speed of light. What you think is normal is strangely askew. IF this is the case, look into busting the job up into pieces.

Steve