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?

2 Answers 2

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."

7
  • 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.
    Commented Jan 7, 2021 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
    Commented Jan 7, 2021 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.
    Commented Jan 7, 2021 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
    Commented Jan 7, 2021 at 18:36
  • Thanks, that helps a lot !
    – Mark B.
    Commented Jan 7, 2021 at 18:37
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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .