The trick to relative symlinks

I learned this week that relative symbolic links are relative to the link not the current working directory. What does this mean?

To remind ourselves, the format of ln is:

ln -s {{/path/to/file_or_directory}} {{path/to/symlink}}

Example

Say we have the following structure:

config/config.yaml
app/index.php

Say we want to create a symlink to app/config.yaml. If we are familar with the cp command we would incorrectly do this:

$ ln -s config/config.yaml app/config.yaml #this is incorrect

Here, we're asking ln to create a symlink in app/config.yaml that points to app/config/config.yaml because the 'source' parameter is relative to the link being created, not the current working directory. As that file does not exist the command fails!

Correct example:

$ ln -s ../config/config.yaml app/config.yaml #this is correct
$ cd app; ln -s ../config/config.yaml config.yaml; cd - #this is clearer

The first correct example can be difficult to comprehend unless we're familiar with this concept: From the perspective of the app/config.yaml file, we need to first go to the parent directory then into the config directory.

This is clarified by the third example: by changing into the destination directory, we align the current working directory with the path to the source.

Notes

If we create absolute symbolic links by providing the full path to the source file, this is avoided, however these links are more fragile. For example when syncing links the absolute path to the source is likely different on another device.

#technology