Правильный способ сделать это - использовать опцию -n, --no-dereference следующим образом.
$ ln -snf foo2 bar
Это заставляет ln рассматривать существующую символическую ссылку как файл. В противном случае он разыменовывает bar с foo1 , спускается в foo1 и использует исходное имя TARGET в качестве LINK_NAME и поэтому в итоге вы получаете символическую ссылку на foo2 , создаваемую в foo1 . В справочной странице по ln говорится следующее ...
-n, --no-dereference
treat LINK_NAME as a normal file if it is a symbolic link to a
directory
Ниже приведен вывод оболочки на моем рабочем столе Arch Linux с версией 8.21 ln с параметром --no-dereference и без него. Я получил те же результаты, что и вы, без параметра --no-dereference , но с использованием --no-dereference вариант сработал как положено.
$ 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