1

if I create a folder inside my current folder, say logs:-

mkdir log
ln -s -f log all_logs

such that all_logs points to the log directory.

ls -ltr
Jan  7 23:33 log
Jan  7 23:33 all_logs -> log

When i run ln -s -f log all_logs again, a recursive symlink gets created inside the log directory, named log.

ls -ltr log/
Jan  7 23:33 log -> log

Why does this happen ? Shouldnt the existing symlink only get unlinked and relinked ( with the -f option) ? Why is this recursive behaviour occurring?

Mark B.
  • 113
  • 4

2 Answers2

1

Extract from the manual (it is the same for mv and cp, though they don't have the 2nd form).

SYNOPSIS
       ln [OPTION]... [-T] TARGET LINK_NAME
       ln [OPTION]... TARGET
       ln [OPTION]... TARGET... DIRECTORY
       ln [OPTION]... -t DIRECTORY TARGET...

Note that the 1st form and the 3rd form (when given 2 arguments), are ambiguous. Therefore to avoid ambiguity: when writing to a directory use the 4th form, and/or append / to the directory name. When using the 1st form (because one is not specifying a directory), use the -T option. Unfortunately this is not available to all, so bugs will happen (thinks will do the unexpected). It this situation -h can be used on BSD, or -n that dose the same, but works on BSD and GNU.

0

Shouldnt the existing symlink only get unlinked and relinked

Nope. The command is resolving the existing link as a directory target, log/.

Symlinks aren't files. For example:

# touch test
# mkdir testdir
# ln -s -f testdir test
# ls -l
Jan  7 11:28  test -> testdir

If the link target is an already existing file, it will be overwritten by the -f option of ln.

If you want to override this behavior on GNU ln, use the -T option to ln, which is "treat LINK_NAME as a normal file always".

If on BSD ln, use -h, which is "If the target_file or target_dir is a symbolic link, do not follow it."

Karu
  • 4,922