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
  • 3

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.

ctrl-alt-delor
  • 2,326
  • 19
  • 29
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,634
  • 7
  • 34
  • 54
  • But isnt the -f option used to overwrite the existing symlink ? What can i do to make the same command be used for both new symlinks and for existing ones ? – Mark B. Jan 07 '21 at 18:26
  • symlinks aren't files. If the file being overwritten is a normal file, -f will do what you expect. If it is an already existing symlink, that symlink gets traversed, and you wind up with a link inside your target directory. I updated my answer. – Karu Jan 07 '21 at 18:29
  • my version of unix doesnt have -T as an option. ln [-Ffhinsv] source_file [target_file] These are the only options – Mark B. Jan 07 '21 at 18:34
  • In that case, use the `h` option. You're on the bsd version of `ln`. `-h` is "If the target_file or target_dir is a symbolic link, do not follow it." – Karu Jan 07 '21 at 18:36
  • Thanks, that helps a lot ! – Mark B. Jan 07 '21 at 18:37
  • "Symlinks aren't files." – By what definition? [POSIX explicitly states that "symbolic link" is a type of file](https://superuser.com/a/1467109/432690). – Kamil Maciorowski Jan 07 '21 at 20:44
  • I should have said *regular* files. This is a distinction made by various userspace tools, where symlinks and directories receive special treatment, despite being technically file entries. – Karu Jan 07 '21 at 20:45