Hacker News new | ask | show | jobs
by icambron 1415 days ago
I use the `ln` command a lot. I use the `man ln` command _almost_ as much.
6 comments

What finally got the `ln` argument order engraved in my mind was learning that you can skip the destination argument:

    ln -s /foo/bar/baz
will create a soft link in the CWD named baz, pointing to /foo/bar/baz.

So you see, if you know that you can always skip the destination, then, logically, the source must be the first one!

I'd say the easiest way to remember the argument order is that it's conceptually the same as for mv and cp: ln -s x y is the closest possible symlink-analogue of cp x y.
Nah, the closest possible symlink-analogue of `cp x y` is `cp -s x y` :-)
This a great way to think about it.
> logically, the source must be the first one!

You mean the target, but that isn’t a logically necessary consequence at all. Conceivably, `ln` could support the following two syntaxes:

  ln [options] target
  ln [options] link_name target
The way I remember the correct parameter order is that I remember it’s the non-intuitive one.
Ah, I remember it is the non-intuitive one, but then when I use it a while, I keep double-guessing which one is the intuitive one.

Kind of like when my wife tells me I'm doing something wrong and she wants it to be the other way.. I know she thinks this thing is important, but can't work out which way she wants it done.

The intuitive one is the order in which `ls` displays it, or assignment order (a := b). That’s how I remember what the intuitive order is. ;)
Surely the intuitive order for mutating assignment is value → name, though...
I remember this as "ln=long -s=short $long $short" as in "ln -s $long $short" creates a $short file pointing to $longfile. But to your point, $short is defaulted to basename($long).
The other way to think about it is that it's the same order as cp.
Finally! Somehow I've never been able to remember that either.
i've always considered manpages to be sort of part of the unix command line experience. since they're fast, it's no matter.

but yea, it took me many years to wire down ln's target link_name semantics for some reason.

what helped for me was to reason about the single argument form. ln -s ~/opt/junk/bin/thinger creates a link to thinger in the current directory. this single argument form is easy to remember, if you want to create a link of course you have to specify the name of the target (from which the link name will be inferred) and since it's the only argument it has to be the first one. now if you want to give it a different name, put the name in obvious still open place, the second argument.

Funny, I always reason about the 3+ argument form... For example, what does ln -s foo bar baz do? Well it can't create a foo symlink that points to bar AND baz, but it could create multiple symlinks - bar and baz - that point to the file foo. Therefore the first arg is the file you want to point to, and the rest of the arguments are symlinks you want to create (of which there happens to usually only be one).

Edit: this line of reasoning works for common usage of a lot of other utils too, like zip/tar etc. Even grep - is it grep FILE PATTERN [PATTERN ...] or grep PATTERN FILE [FILE ...] ?

“Same argument order as cp” always helped me.
Mnemonic: “What you have to what you want”
i'm enjoying seeing the variety in everyone's mnemonics :)
I learned to behave as if there is no second argument for ln. Instead of doing `ln -s path/to/foo bar` I do `ln -s path/to/foo` then `mv foo bar`. Of course it doesn't always work, but covers most use cases for me.
I generally only need `ln -s <src> <dst>`. I know the -s means symbolic link, but in my head I read it as "source", since that's how I remembered the order long ago.
This is confusing, because when you picture the link as an arrow (as in `ls` output), the link name is the source and the link target is the destination.