Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I have 2 directories (FOO, LALA). I create a symbolic link in one of them like this

ln -s /etc/apache2 FOO/apache2

Afterwards I want to create another symlink, pointing to the same directory, but not using the initial directory but the symlink created. So I try

ln -s FOO/apache2 LALA/apache2

The problem is that the second link is invalid.

ls FOO/apache2

The above works and lists files in /etc/apache2

ls LALA/apache2

But this one doesn't. It just lists the link itself. If I add a slash at the end of each ls

ls FOO/apache2/

Works as well.

ls LALA/apache2/

I get ls: cannot access LALA/apache2/: No such file or directory/


If instead of

ln -s FOO/apache2 LALA/apache2

I do

cd LALA ; ln -s ../FOO/apache2 apache2

Then the symlink is valid

Any idea what's the difference?


Initial question from here http://stackoverflow.com/questions/10656666/use-a-symbolic-link-to-create-a-new-symbolic-link

share|improve this question
add comment

1 Answer

up vote 1 down vote accepted

The difference is that relative symlinks are resolved at access time, not creation time.


In your first example, if the link's name is /somedir/LALA/apache2 and its target is FOO/apache2, it will be resolved to /somedir/LALA/FOO/apache2 when accessing it.

link name:                link target:    absolute target:
"/somedir/LALA/apache2" + "FOO/apache2" = "/somedir/LALA/FOO/apache2"

In the second example, the link's name is same – /somedir/LALA/apache2 – but its target, ../FOO/apache2, is now resolved as:

link name:                link target:       absolute target:
"/somedir/LALA/apache2" + "../FOO/apache2" = "/somedir/LALA/../FOO/apache2"
                                           → "/somedir/FOO/apache2"

This means that you must always give "../FOO/apache2" as the target to ln -s when creating the second link, regardless of what directory you are currently in.

Note: In the latest version of coreutils, the ln command has a new option -r/--relative, which does the job for you. For example, ln -r -s FOO/apache2 LALA/apache2 would work correctly.

For older versions, you could hack something with realpath --strip --relative-to...
I wrote sym for my own use.

share|improve this answer
    
Great. That was the problem... Really strange if you ask me. I'll probably end up using readlink in the first symlink and create the second one with the result from readlink as the target. –  George Kastrinis May 18 '12 at 19:37
    
@GeorgeKastrinis: Maybe this script will be useful. –  grawity May 18 '12 at 19:41
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.