How to overwrite a symbolic link of a directory?

There are two directories foo1 and foo2.

At first I make a directory symlink by ln -s foo1 bar. After that I want to change the symlink, so I typed ln -sf foo2 bar

But bar is still linked with foo1. Symlink foo2 is created inside of foo1.

What should I type when I want to replace foo1 by foo2?

I tested in three environments.

  1. Ubuntu 12.04, ln (GNU coreutils) 8.13
  2. CentOS 6.4, ln (GNU coreutils) 8.4
  3. OS X 10.7.5, ln (without version)

The proper way to do this is to use the -n, --no-dereference option like so.

$ ln -snf foo2 bar

This causes ln to treat the existing symlink as a file. Otherwise, it dereferences bar to foo1, descends into foo1 and uses the original TARGET name as the LINK_NAME and that's why you end up with a symlink to foo2 being created inside the foo1 directory. The manpage on ln states the following...

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

Below is the shell output on my Arch Linux desktop with version 8.21 of ln with and without the --no-dereference option, I got the same results you did without the --no-dereference option, but using the --no-dereference option it worked as expected.

$ mkdir foo1 foo2
$ ln -s foo1 bar
$ ls -l bar
  lrwxrwxrwx 1 drew users 4 Sep 17 12:51 bar -> foo1
$ ln -sf foo2 bar
$ ls -l bar
  lrwxrwxrwx 1 drew users 4 Sep 17 12:51 bar -> foo1
$ ls -l foo1
  total 0
  lrwxrwxrwx 1 drew users 4 Sep 17 12:51 foo2 -> foo2
$ ln -snf foo2 bar
$ ls -l bar
  lrwxrwxrwx 1 drew users 4 Sep 17 12:52 bar -> foo2