ln

Table of Contents

Relative source path of symlink discussion

It's important to realise that the first argument after ln -s is stored as the target of the symlink. It can be any arbitrary string, but at the time the symlink is being used and resolved, that string is understood as a relative path to the parent directory of the symlink (when it doesn't start with /).

foo
Hello, World!
mkdir a
# This won't work, because `a/foo` points to `foo`, relative to `a/`.
ln -s foo a/foo
ls -lh a
total 0
lrwxr-xr-x  1 yeonghoey  staff     3B Aug 13 15:54 foo -> foo
mkdir b
# Now this works, `b/foo` points `../foo`, relative to `b/`
ln -s ../foo b/foo
ls -lh b
cat 'b/foo'
total 0
lrwxr-xr-x  1 yeonghoey  staff     6B Aug 13 15:58 foo -> ../foo
Hello, World!

Subtlety of Following Symlinks discussion

The general rule is,

if a command operates on links (i.e. directory entries, which are pointers to inodes)
The command treats symlinks as themselves rather than as the object the link points to.
$ mkdir a
$ ln -s a aa
$ cp -R aa b  # -R, because followed 'aa' is a directory
# ----------------------------------------------
a
aa -> a
b -> a
# ----------------------------------------------
# 'b' is a copy of the symlink ('aa'), not the actual file ('a')
Otherwise
The command operates on what the symlink points to.
$ touch a
$ ln -s a aa
$ cp aa b
# ----------------------------------------------
a
aa -> a
b
# ----------------------------------------------
# 'b' is a copy of the actual file ('a')