0

Can one force ln not to follow a soft link in its first argument? For example, in the following I would like hard to be a hard link to the soft link soft:

$ mkdir dir
$ ln -s dir soft
$ ln soft hard
ln: soft: Is a directory

I know about ln -h, but this only prevents ln from following soft links in the second argument.

2
  • Works for me on GNU/Linux. What system are you on?
    – ilkkachu
    Sep 21, 2021 at 20:33
  • 1
    @ilkkachu They are showing the error that ln on a BSD system would produce. GNU ln also does this on BSD systems (gln: soft: hard link not allowed for directory).
    – Kusalananda
    Sep 21, 2021 at 20:53

1 Answer 1

2

By default on your system, ln resolves the source fully if it is a symbolic link. There is a standard option, -P, that prevents it from doing this:

$ mkdir dir
$ ln -s dir soft
$ ls -l
total 4
drwxr-xr-x  2 myself  wheel  512 Sep 21 22:39 dir
lrwxr-xr-x  1 myself  wheel    3 Sep 21 22:39 soft -> dir
$ ln -P soft hard
$ ls -il
total 4
129605 drwxr-xr-x  2 myself  wheel  512 Sep 21 22:39 dir
129606 lrwxr-xr-x  2 myself  wheel    3 Sep 21 22:39 hard -> dir
129606 lrwxr-xr-x  2 myself  wheel    3 Sep 21 22:39 soft -> dir

The POSIX specification for the ln utility says:

If source_file is a symbolic link:

If the -P option is in effect, actions shall be performed equivalent to the linkat() function with source_file as the path1 argument, the destination path as the path2 argument, AT_FDCWD as the fd1 and fd2 arguments, and zero as the flag argument.

This text is mostly gibberish unless you know what linkat() is. The OpenBSD manual translates this into

-P

When creating a hard link and the source is a symbolic link, link to the symbolic link itself. The -P option overrides any previous -L options.

... and the GNU manual says

-P
--physical

If -s is not in effect, and the source file is a symbolic link, create the hard link to the symbolic link itself. On platforms where this is not supported by the kernel, this option creates a symbolic link with identical contents; since symbolic link contents cannot be edited, any file name resolution performed through either link will be the same as if a hard link had been created.


Interestingly, GNU ln on (Ubuntu) Linux has this in the manual:

Using -s ignores -L and -P. Otherwise, the last option specified controls behavior when a TARGET is a symbolic link, defaulting to -P.

Whereas on OpenBSD and macOS (and presumably on other systems as well), the same GNU ln manual says

Using -s ignores -L and -P. Otherwise, the last option specified controls behavior when a TARGET is a symbolic link, defaulting to -L.

(Another reason to always read the manual on the system you're using rather than on some random page on the internet, which seems to happen far too often.)

5
  • On my (ancient) system ln does not have the -P option! This does seem to solve the question though.
    – Olius
    Jun 12, 2022 at 18:54
  • @Olius May I ask what system you are running where ln does not have a -P option? AIX 7.1?
    – Kusalananda
    Jun 12, 2022 at 19:38
  • OS X 10.11.6; uname -v gives Darwin Kernel Version 15.6.0: Thu Jun 21 20:07:40 PDT 2018; root:xnu-3248.73.11~1/RELEASE_X86_64. It's the last Apple OS to run on my 2009 dinosaur…
    – Olius
    Jun 12, 2022 at 21:55
  • @Olius Is there a chance you could run GNU ln via coreutils on it? Is Homebrew or Fink or MacPorts available on it?
    – Kusalananda
    Jun 12, 2022 at 22:44
  • My friend who needed this is running GNU ln. If I remember correctly we were trying to build some funny recursive directory structure when we asked ourselves this question. Not vital for me, but I can definitely get GNU coreutils through Homebrew. Thanks!
    – Olius
    Jun 12, 2022 at 23:16

You must log in to answer this question.

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