Symlinks to symlinks

Really interesting problem.

It appears that that there are two limitations regarding symlinks (at least in Manjaro XFCE).

1) Only absolute (ie. no relative) symlinks can be made from Thunar: When you use Ctrl+Shift drag to make a symlink in Thunar, the symlink created is always absolute. To create a relative symlink you need to use the -r option in the command line (eg. ln -sr <FILE_TO_LINK> <DESTINATION>. It’s not a big issue, but noteworthy because…

2) BIGGER ISSUE: Cannot make a symlink that points to a symlink from the command line: I can trivially do this from Thunar but surprisingly when I attempt this from the command line, ie. ln -sr <SYMLINK> <DESTINATION_SYMLINK> the created link point to what the first symlink points to, instead of pointing to the symlink.

Therefore between 1 and 2 I’m not able to fulfill my use case, which is a relative symlink that points to a symlink.

Am I missing something?

cd ~/.local/bin
echo "echo baz" > baz.sh && chmod +x baz.sh
ln -s baz.sh link1
ln -rs link1 ../link2  # or ln -s bin/link1 ../link2
ln -s ../link2 link3
link3

What’s not working?

man ln:
-r, --relative
              create symbolic links relative to link location

the created link point to what the first symlink points to, instead of pointing to the symlink.

It points to the link location - where the already existing symlink points to as well.
(will keep working, even if the first symlink is removed)

Therefore between 1 and 2 I’m not able to fulfill my use case,

Where would be the difference?
You want to force an indirection? (link pointing to link pointing to what is meant)

Yes, it does it. The relative symlink follows the link to the file! If we delete Link1, Link2 still works. Its quite strange.

That is not the case for Link3. If we remove link2 then link3 breaks as expected.

Bingo, yes. Disable a thing by removing a link.

EDIT: It’s weird that ‘relative’ symlinks do this extra thing, right?

Ah I see what you mean. Well -r seems to follow/resolve the symlinks. Use ln without -r and specify relative path yourself, then it will work your way. So in my example use the commented out command.

EDIT: Added ‘seems to’, since this is an observed thing and therefore not written in manual.

And since it also seems that you want to dissect this into oblivion, I suggest you running it with strace or looking at the actual code.

$ strace ln -rs link1 ../link2
[...]
getcwd("/home/zbe/.local/bin", 1024)    = 21
readlink("/home/zbe/.local/bin/link1", "baz.sh", 1023) = 6
readlink("/home/zbe/.local/bin/baz.sh", 0x7ffcb02ce720, 1023) = -1 EINVAL (Invalid argument)
symlinkat("bin/baz.sh", AT_FDCWD, "../link2") = 0
[...]
$ strace ln -s bin/link1 ../link2
[...]
symlinkat("bin/link1", AT_FDCWD, "../link2") = 0
[...]

https://linux.die.net/man/2/readlink
https://linux.die.net/man/2/symlinkat

1 Like

This is beginning to sound like an Abbott and Costello routine…

1 Like

Why do you think that’s a thing you can do? :thinking:

1 Like

Because it’s possible — if the correct syntax is used. :wink:

1 Like

Wow. You are 100% correct with those instructions for the command! Thanks! :smiley: :smiley: :smiley:

Having said that we don’t know where you got the information that [-r] “resolves”. My manual says:

man ln
-r, --relative
              with -s, create links relative to link location

…which would seem to be incorrect/incomplete manual information. I tried the verbose [--relative] too and it also ‘resolves’ as well! Notice that my manual only differs very slightly from the manual @Nachlese provided above, but it does differ, and even @Nachlese 's description doesn’t mention the added side-effect of ‘resolving’.

In fact nowhere in my manual is ‘resolve/resolving’ discussed.

This would obviously be an upstream issue but perhaps the developers of a possible --resolve (-R ?) option made a mistake and included it in the [-r] option??? Also, I’d write that [-r] flag “actively strips common folders from the provided TARGET and LINK to ensure the resulting link is relative” and put forward the notion that the verbose form of the option should probably be --force-relative not simply --relative because its entirely possible to create relative links without it.

I’ll leave those as exercises for the curious reader/maintainer. :slight_smile: PROBLEM SOLVED VIA GUIDANCE. If anyone makes an upstream ticket re above, please link it below. If I’m wrong, do tell me.

Of course you don’t - but, of course, I do. :grin:
I’m currently on Linux Mint, and that is what man ln shows me there.
Would not have expected such differences between different versions of the manual pages.

My ln version is:

ln --version
ln (GNU coreutils) 8.32

Don’t know about the version of the manual page for it.

1 Like

Yeah, its likely what you say, the manual, given the version here is more recent (GNU coreutils 9.3). Hi @Yochanan, any ideas? My man-version is at man 2.11.2 and man-pages 6.05.01-1 :slight_smile:

Manjaro currently has coreutils 9.4.2 (inherited from Arch) on all branches

GNU online documentation has more information about ln command
ln invocation (GNU Coreutils 9.4)

1 Like

Using pacman --sync ln or pacman -S ln should help; assuming no other factors interfere with the premise. I’m assuming the confusion above was simply due to different update states.

You can’t use 2 operations (both syncs in this case) in one command.

-S, --sync
           Synchronize packages. ...
1 Like

Did an update:

pacman -Sy coreutils

Now at version gnu-coreutils 9.4 yet the man page is unchanged.

Your confusion, as demonstrated above, is due to not understanding the use of ‘resolves’ in this context. It refers to the intended result; you could just as easily substitute that for ‘translates as’, ‘results in’, or ‘equals’, for example.

It’s simply word usage, and not meant to describe any specific function of ln. The use of ‘resolves’ is therefore irrelevant to any apparent differences in the manual descriptions.

Does this help clarify your understanding?

Completely unnecessary, because Manjaro is a rolling-release distribution, and if you kept your system up to date, then you already are on the latest version of everything.

Also, never update only one package, because this will lead to a partial-update state — read: breakage — and we do not offer any support for that.

Because @Nachlese mentioned a more complete manual (via their stated Linux Mint) I did some extra digging online.

To my surprise it turns out there is intended “resolving” being done for relative links although the reasoning is beyond my comprehension at this time. A claim provided is it “gives greater control over relative file name generation” that does quite make sense to me yet, and there is some sort of test using a syntax I’ve not come across so don’t understand.

Basically my man page appears unchanged, still no mention of this “resolving” side-effect and yes the man page says coreutils 9.4, so its definitely the latest.

Does anyone here know what makes “forcing” relative links special here, that they require resolving the symlink? But not when specifying normal symlinks. It so far seems arbitrary to me, but I’m no expert on symlinks.

Thanks yes I know it can be risky, and on second thoughts maybe being coreutils, this is an EXTRA BAD idea. As an aside, I just tried a proper pacman -Syu update and a “could not satisfy dependencies” error “kvantum (1.0.10-2) breaking dependency ‘kvantum-qt5’ required by kvantum-theme-matchama”. Maybe I really have broken something and should timeshift as there is nothing about this error on these forums. I get to approve a bunch of mostly KDE packages moving to the ‘Extras’ repo but after that pacman exits in error. I see that pacman requires coreutils too, may I will timeshift. **Don’t let this distract from the topic though, because…

…I really want to understand this symlink kink. :stuck_out_tongue:

To address your other issue:-

sudo pacman -R kvantum-theme-matchama

This theme is no longer supported on Manjaro, and needs to be removed. If you search the forum you’ll find others with the same issue.

Additionally, symbolic links resolve to the target they point to – this is what they do – however, it’s not a specific function that you have any control over.

I’ve already attempted to explain this above. Did you bother to read it fully? You don’t need to comprehend it, just let it happen. :slightly_smiling_face:

2 Likes

The code in ln does apparently. I really don’t see what is it to understand here.

And “relative” in this case means (IMHO) relative to the directory where you are putting the symlink in. In other words, when you do ln -rs /some/path/file /some/other/path/link it calculates what is the relative path from /some/path/ to /some/other/path/ so you don’t have to, and by doing so, the code apparently resolves any symlinks too.

Why is it so? Because someone wrote it like that. :man_shrugging:

I also updated my answer. Now you can check strace, syscalls and source code and write a thesis on symlinks. :stuck_out_tongue:

1 Like