LN Command – What is `ln –no-dereference` Supposed to Do?

ln

I'm refreshing my understanding of a few basic GNU/Linux commands that I admit that I never really understood fully for the last 20+ years.

$ man ln in part says:

-n, --no-dereference
          treat LINK_NAME as a normal file if it is a symbolic link to a directory

To try to understand this better, I broke this down as follows:

$ mkdir dir1
$ ln -vs dir1 dir2
'dir2' -> 'dir1'
$ mkdir dir3; touch dir3/xx

$ tree -F
.  
├── dir1/  
├── dir2 -> dir1/  
└── dir3/  
    └── xx  

#Now to test -n, first as a hard link
$ ln -vn dir3/xx dir2
ln: failed to create hard link 'dir2': File exists

# and second as a symbolic link
$ ln -vsn dir3/xx dir2
ln: failed to create symbolic link 'dir2': File exists

# ??? why do these both fail ???

Only the first command form in the SYNOPSIS calls out a 'LINK_NAME', in this syntax:

   ln [OPTION]... [-T] TARGET LINK_NAME

so this says that the -n and --no-dereference options ONLY relate to the first command form for ln, (and not the other three command forms).

In my example:

The TARGET is dir3/xx, and
the LINK_NAME is dir2 ('a symbolic link to a directory').

So the manual says that if LINK_NAME (i.e. remember this is the name of the link we are supposedly creating) is 'a symbolic link to a directory'…

… then we are suppose to treat this symbolic link as a 'normal file'.

What am I missing?

Best Answer

Without -n, both your ln commands would create links inside dir2: if LINK_NAME exists and is a directory or a symlink to a directory, the link is created inside the directory (if possible).

That’s what -n changes here: ln won’t consider LINK_NAME as a directory (if it’s a symlink). Since LINK_NAME already exists, ln fails. Adding -f will cause the existing symlink to be replaced:

ln -nsf dir3 dir2

will replace dir2 instead of creating a link inside dir2.