Am I the only person who, after 30 years of using `/bin/ln`, *still* gets its arguments backwards?
If I type:
$ ln -s x y
My mind is always thinking: “I want a symlink where x ⇒ y”, and as such I incorrectly put the destination *before* the source.
I am sure `ln` is this way in #POSIX to match the behavior of `cp` & `mv`. The latter two are intuitive to me because I read it as “copy/move x to y”.
$ ls -l y
lrwxrwxrwx 1 bkuhn bkuhn 1 May 2 14:39 y -> x
“y ⇒ x” … See!?!?!
@bkuhn i mean, i haven’t even been alive for 30 years, but i make this mistake all the time
+1
@bkuhn I stopped doing that mistake when memorized that the first one is "what already exists", which I just realized also works for 'cp' and 'mv'.
@bkuhn pretty much every time
Sometimes I'll think to just type it without args to get the sequence
@shrub900
I'm admittedly jealous b/c you had access to a #POSIX system (& a #FOSS one too!) from your earliest computer-using time in life.
I “wasted”¹ my teenage years with a Commodore 64² — writing in BASIC & 6502 assembler.
I was ≈ 18 years old before I got access to a “real” computer running #Unix SYSVR3.2.3 & ported #GNU #Emacs to it.
¹ I learned useful skills, but it yielded no useful artifacts.
² Yes, @cwebber, I *was* keeping up with #Commodore, but it was *not* keeping up with me!!
@bkuhn The way I fixed it in my head was when I memorised that if you leave out the second argument, it makes the link in the CWD with the name of the first argument. So obviously the first argument is the target, because the second argument is optional!
@spacehobo I actually hate that feature. It just confuses me more!
Yeah, I tried that, like, 20 years ago or so? It works for me to immediately realize what went wrong when I do them backwards, but does not stop my fingers from typing it backwards first.
@bkuhn every single time
@bkuhn With -s I'd more compare the behavior to chmod/chown given it's non-mangled and so relative to the symlink location, you write the link target (1) into a symlink file (2).
@lanodan wrote:
> “With -s I'd more compare the behavior [of /bin/ln -s] to chmod/chown given it's non-mangled and so relative to the symlink location, you write the link target (1) into a symlink file (2).”
That's a good point. Ultimately, a symlink is not really a file in the way humans think of them. (And literally is *not* a “regular” file under #POSIX).
I wonder if there's a sensitive dependence on whether one learned AT&T vs Intel assembly syntax
I find trouble with systemctl subcommand ordering but not, for example git subcommand ordering
Fascinating! I don't remember one lick of 6502 Assembly, but perhaps it warped my programming brain in a manner that is completely subconscious.
🤔
Sorry, I can only say I make that mistake routinely after 27~28 years of making symlinks with the "ln" command...
I have no idea what that would be like after 30 years!
@vagrantc I'll tentatively predict it won't change in 3 years, but now that I drew it your attention, perhaps I've changed the outcome by observing it!
I do like your confidence in your capacity to learn new things. I suspect it's well founded. ☺
I'm sure I just don't make enough links (hard or sym) to be able to retrain in the time allotted.
And I am probably the last person on the planet that likes to use hard links!
Cc: @spacehobo @downey @mezzo @elebertus @lanodan @north @rmsilva @gvlx
@bkuhn same after 15 years. I expected to get it right until 30 years passed.
But ln is a special case:
ln [opts] TARGET LINK_NAME
Usually I expect the target to be the last argument, DSL semantics of a teleological projection.
But when linking, the target is the link name during linkage, but after linkage is done, the source of operation becomes the target of the link.
It's similar confusing to write a clean linked list interface in C IMHO.
Hope this helps. For my case it still didn't.
@bkuhn Using ln is like plugging in an old USB cable for me. It doesn't work the first time, the second time or the third time....
I always mess up -p and -P when I'm using scp as well. Why is it different between ssh and scp??
@bkuhn just recompile coreutils with https://gnu.wildebeest.org/~mark/ls.patch
$ src/ls -l y
lrwxrwxrwx. 1 mark mark 1 mei 2 23:57 x <- y
@mjw
😆 🤣 🤣 🤣 🤣 🤣
Interesting idea (& applies software freedom to the problem 👍) but it's diabolical! Either
(a) I do it only on machines where I'm the only user — in which case I mess with my own mind on servers that I use, or
(b) I mess with *everyone* else's mind on those servers.
Yes, I could make /usr/local/bin/bkuhn-ls and alias both in my account & for root if it's me su'ing. 🤔
BTW, at first I thought you were suggesting I change `ln` instead — which is *really* a mind🤬!
Cc: @vagrantc
re: ssh/scp w/ the -p and -P.
Oh, geez, yeah! 😠
I *quit* using `scp` *entirely* at least 20 years ago. Since then, I just always use `rsync` (with `-e ssh <args>` when needed) even when `scp` would do just fine for the purpose. & I do that *precisely* because of `scp`'s -P/-p mess!
re: USB cable: I don't mind that when 2x works. However, some ports that I regularly plug/unplug require a bit too much pressure even when properly oriented, then I do need 3+x retries & 😡.
@bkuhn @idlestate @lanodan @shrub900 That one may not count, as the target register was often in the mnemonic itself (i.e. `LDA`, `LDX`, `LDY` to load the operand into the A, X, or Y register).
Oh, here's an idea:
do you think coreutils would accept an upstream patch that added a command-line option and/or environment variable that changed the output?
That would mess with people's minds less, and once it rolled out upstream, it'd eventually be everywhere for me to use it!
@bkuhn I think I was doing pretty good with it just by remembering that it feels counterintuitive. Unfortunately, reading your post got me turned around again so my success rate will probably bldrop back to 50% for a while.
@bkuhn it has the same order of arguments as cp and mv.
@bkuhn it hasn't been quite 30 years for me, but yes. Every time. I have to look it up, again.
I do not know why but I do not make this mistake anymore. I think I did not do it since at least 25 years.
I think my brain exploded first time I had to explain it to students and since then has been glued in the "right" way.
'ln -s x y' is understood by my muscles as: copy/put the path x as the content of the y file (exactly as cp or mv).
For me content of symbolic links are just path.
I do not think at the 'ls: representation when using 'ln -s'.
@bkuhn @mjw There was a relatively long bug report discussing different ways to make this less confusing a few years ago: https://bugs.gnu.org/52115
I think I agree with Bernhard for the most part. Especially that the synopsis of 'ln' is a bit of a mess that we should avoid complicating further.
@bkuhn I've hammered into my brain "I'm creating a new thing y that points at x" so "ln x y" comes more easily to me now. But I still check after creating the symlink.
I thought @mjw was taking about 'ln' too at first but I did mention how my problem was caused initially by what 'ls' displays.
Given that there are so many ways to change what 'ls' outputs already, adding one more knob seems safe to me.
Maybe upstream will take it.
While I'm at it, I wonder if we can do better than a single integer to help us know a hard link is in play, but surely that's filesystem dependent re: whether more info is available.
Cc: @liw
@bkuhn I tricked myself into remembering this by telling myself that I can create multiple links to one source, and so of course the new names have to be last because you can have as many of them as you want. Which of course you can't, but don't tell me that, because it works and I never need to do that anyway.
That bug fails to notice that it is using confusing language in the documentation.
ln TARGET LINK_NAME
the target can reasonably be assumed to be the file that is created. But in the case of ln, it's the target *of* the file that is created.
I think that is where my confusion stems from, and I think this language should be updated.
I can't quite think of a good replacement for TARGET, though.
@bkuhn @mjw
I learned cp and mv as 'source' to 'destination', so I think the 'ln' docs really should say:
'ln <source> <link_name>'.
But the whole ambiguity of the word 'target' speaks to why “just think of it like cp or mv" doesn't work for many people — especially for symlink.
You point/follow a symlink somewhere… like a target?
You cp a file somewhere … like a target?
@bkuhn @wouter @mjw @collinfunk @pinche_compinche This is why man strstr gives the arguments as haystack and needle instead of trying to use the word target.
Anyone who tries to parse the ls output for symlink status rather than using https://manpages.debian.org/trixie/coreutils/stat.1.en.html (and doesn't do so in a shell with potential output-changing environment variables cleared) deserves for their scripts to be broken.
ls is an interactive program, its output should not be considered parseable.
@bkuhn @vagrantc @mjw
- replies
- 1
- announces
- 0
- likes
- 1
Indeed, what @wouter said!
Frankly, if any script, Makefile, tutorial, or tech support is relying on the 'ls' output with additional options to look a specific way, then something is more likely wrong with those Makefiles, tutorials, or tech support folks' training.
You could have made the same argument when '-h' was created as an option to 'ls'.
Anyway, maybe you misread the thread? No one was actually suggesting changing 'ln'. (Ah,you replied to say that)
Indeed, I initially thought @mjw was making a joke-patch for 'ln', which is where the confusion started. In fact, mjw made a ha-ha-only-serious patch to 'ls'.
Whether 'strstr' should exist at *all* is another matter entirely. 🤣
Although you may be too young to remember that there was a SYSV release in which its libc's strstr(3) had a huge buffer-overflow and no one in the SYSV userbase trusted it anymore (even after the bug was fixed). I remember distinctly trying to port glibc to SYSV just to get strtstr(3) back and my boss said it was a waste of time & just use another library.
@bkuhn @mattskala @wouter @vagrantc Turns out for soms reason the coreutils testsuite expects ls -l outputs forward implication x -> y instead of the imho more correct backwards implication y <- x. So some testsuite tweaks will still be necessary.
Oh no. That was discussed in a bug report that this thread links to, but that's a terrible idea.
This is about adding an *option* to ls to swap the symlink and what that points to around in the ls output.
@bkuhn @vagrantc @mjw
Wait, @mjw, were you already thinking about this issue before I posted it?
It seems like you thought about it before?
Regardless, this backwards implication idea is amazing. And can't you just add it as an option and also update the test suite?
@bkuhn as you say, I made peace with it the day I started thinking about it as cp.
"This thing exists here and I want to exist there: cp here there"
"This thing exists here and I want it to exist there: ln here there"