I always forget the argument order of the `ln -s` command
reddit.com
reddit.com
$cp file_from file_to
and that
$ln -s link_from link_to
has a very similar effect to the cp command above. I haven't messed this up ever since.
Also I wonder how many people can say the same thing as the article and still get upvoted.
cp -l from toIs the "from" the file/dir I want to copy "to" a link?
Or is the "from" the name of a link I want to point "to"?
The dual meaning of some terms that the concept of links and making links creates causes a lot of this confusion, IMHO. Are we using terminology that refers to the act of creating the link or that refers to the direction of the link?
Similarly, I don't think it helps that the usage text and manpage for ln refer to "target"s.
(I know what you mean by your examples but I wanted to share my pet theory as to why this is always so hard to remember)
And people say Linux isn't user-friendly! :)
$chown user1 file1
$chown user1 file2
$ln -s file1 file2
$ln -s file1 file3
...seems more likely than... $chown user1 file1
$chown user2 file1
$ln -s file1 file2
$ln -s file3 file2flip would actually be quite useful for me on grep. I often search the some corpus of text, but change the pattern.
I am often guilty of this myself. At first I used to read all of the stories that were linked to on HN, along with the comments. But I quickly learned that the comments were often much more interesting/useful than the stories themselves.
So now I just look at the comments first, by default. And only in exceptional cases do I actually bother to read the article. There's just not enough time..
HN is an overwhelming firehose of information even without reading every article that seems interesting. But reading the comments can usually quickly give you a good feel for whether the story is worth reading or not. In this particular case, I think not.
`$ ln -s link_from link_to` would imply the reverse behavior. How does a symlink point from the actual file to the thing-that-looks-like-a-file-but-is-really-a-symlink? The file doesn't even know whether there are symlinks pointing to it.
Applying your definitions of "link from" and "link to", this:
<a href="http://google.com/>Google</a>;
creates a link from google.com to the hyperlink on your site.
I find the top reddit comment:
cp existing new
ln -s existing new
much, much more useful. You want to create a new link pointing to an existing file, which has the same ordering as when you use cp to create a new file with the content of an existing file.It took me a long time till I realized that saying it thus made me always recall it properly.
cp existing_thing new_thing
ln -s existing_thing new_thing ln -s 'the one that exists' 'the one that doesnt exist'
I actually say that to myself as I'm typing the command. Since I started doing that, I've never gotten it wrong. strcat(target, source)
strcpy(target, source)
But, in SH... cp source target
I feel like these things were developed around the same time, by the same community. I've always wondered if there was a reason for the different perspective.Why memcpy was parameterized in that order, I am not certain.
lvalue == write location rvalue == read location
It comes from assignment syntax where the left hand side is the target of the assignment and the right hand side is the source. So this makes a ton of sense in C.
OTOH, the Bourne shell was built independent of the C programming language. The Bourne shell inherited a bit from its predecessor the Thompson shell which introduce the concept of command piping. In this case, all operations followed the pattern of data flowing to the right. This is the opposite of how assignment works in all programming languages where data flows to the left.
That's why shell commands generally move data from left to right based on their argument ordering.
FWIW, tar is unique because tar wasn't meant to do archiving to files. If you just did `tar c directory' it would archive the directory to a tape device. The `f' flag is there to redirect the output to a file (instead of the default tape device). So `tar cf foo.tar directory' is not backwards, it just uses an unusual argument convention. The modern form would be `tar --file=foo.tar create directory'.
The curious bit is, AT&T assembly syntax does follow this convention so you'll see something like `mov $5, ax'.
expression -> variable; expression memory-location !
to store and memory-location @
to read.* for a slightly smaller definition of everything than in Plan9
Ever notice that for everything in the world that screws, like valves or screws or bottle caps, counter-clockwise loosens and clockwise tightens? How is it we got the whole world to agree on that convention, but software is 50/50 on how we order the source and destination?
"Forward" is also "tighter", apparently.
tar [args] [one thing] [list of things]
it'd be wierd if it was
tar [args] [list of things] [filename]
... but i will admit i frequently make that mistake.
cp [args] [list of things] [destination folder] cp [args] -t [destination folder] [list of things]
The same is true of mv. This is useful if you are piping filenames to xargs. tar [args] [list of things]
where [args] may contain [-f filename], among other things.That is, the destination filename is an optional argument; by default tar outputs to a tape device or stdout, depending on the implementation.
At least in GNU tar, the target filename can very well be specified as the last argument:
tar -c foo.txt bar.txt baz.txt -f stuff.tarFor "mv A B"
I've no problem saying either
mv into A the contents of B
or mv the contents of A into Bhttp://en.wikipedia.org/wiki/Lug_nut#History
Propane tanks also used to have backwards screwing connections. I believe this was a safety 'feature' given the mainstream use of small propane tanks. Having them tighten counter-clockwise prevents similar looking but wrong hoses from being attached to the tank. It also tricked people who didn't understand propane tanks form being able to remove a connection (since they would usually just tighten it further).
Same with some of the LP gas cylinders I have encountered here in Aus.
mov a,b
as from b to a.Intel:
mov bx, 100
AT&T:
mov $100, %bx
"cp" is trying mirror how we do things in real life: if you want to take some things from one place and put them in another, you first pick them all up (hence the first argument), walk over to the destination, and then put them down.
*target = source*
Step two is realizing that things don't work that way in C. Step three is sprinkling in semantic sugar to make it work.strcat, then, is for symmetry with strcpy.
ln -s path1/files* path2/
or ln -s path1/* .
Doing that helped me remember the order because I knew my command could end with a directory as the destination and links would be created there.Sometimes hardlinks are useful too. You don't always need -s
Edit: Why was this downvoted? I didn't see anyone else mention it until after my post and to me this was an easier way to remember the order than comparing it to "cp".
I have a folder. I want to link that folder to some other name, over yonder. " ln -s foo bar". See?
"I want to copy this <source> to this <destination>"
vs.
"I want this <source> to be accessible via this <link>"
link -> original
So naturally you want to say that in the command, "make a link that points to the original".I had a friend who gave up and made an alias that sorted out which of the arguments existed and did The Right Thing.
I'm thinking like an IDE will pop up some help text when you begin typing a function name or a recognised special word. Why doesn't the standard sh (bash for me) give me similar help, as I type "ln" it could give me a pop-up with the possible completions and then as I get to "ln -s" it could remind me with "TARGET [NAME] // will create a file named NAME that is a soft link to TARGET, or use TARGET's name if NAME isn't specified". You get the picture.
In a pure text env the help could appear on the next line highlighted appropriately or could be to the right of the cursor or somesuch.
I'm hoping someone will say $CONSOLE does that already ...? Anyone?
I think that there could be a place for a modern, more graphical orinted command-line interface. In addition to inline help it could display tables more nicely, maybe even allow proportional fonts. And while we are changing stuff, then maybe the object passing idea could be taken from PowerShell.
* The arguments order is just the opposite of common sense. It has taken me years to really remember it, and I still have to think a little every time I use it.
* The default is to create hard link, which you almost never want. And if you do want them, you are probably doing it wrong. Making hard links is just asking for trouble.
I've read that Plan9 has somewhat corrected this whole problem. At least there is no ln command at all. Instead one uses bind, mount, and unmount. Of which bind is most similar to ln -s, but with arguments in reversed order.
mklink link_to link_from
EDIT: formatting.
You start with "ln -s A B" and realize you always make the mistake, so you force yourself to do the opposite of your natural instinct: "ln -s B A". It works until this becomes natural but you still think you always get it wrong, so start doing the opposite of your new natural: "ln -s A B". You'll now be very confused until you force yourself to learn it for good.
This happens to me all the time for various binary things.
ln -s source fakename
Everyone prefers real to fake*
ln -s real fake
Now you will never forget.* Yes, I realise this isn't strictly true
As other people have mentioned, thinking of it in terms of the files created (ala cp) has helped to learn the correct behavior. I think this is a case where some minor change in the documentation might help to avoid the whole problem.
ln -s new_link (onto) existing(chain)
Obviously the target isn't a chain but the association between links and chains is a strong one.
In other words I don't think of creating a link as creating something new _from_ something that already exists, I think of it as adding something new _to_ something that already exists.
ln -s target link_nameln -s file <== symlink
Always remember that. Pointing left. The symlink is pointing at the file.
cp original copy
ln -s original linkIt's kind of a dumb way to think of it, but it seems to work for me.
alias ln='ln -s'
to your .bashrc? A quick test of this in my terminal and the alias takes precedent over the ln command. Although, I guess it'd be worth doing a few tests to make certain!
"what you already know" being the existing file and the second part being the name of the link to the existing file.
I never got it wrong again.
But yeah, it's weird that it's opposite of ln.
...because I met the `man` command.
(not "from"/"to", which is ambiguous)
ln -s real fake
Not like that.
from to
source target
Hell, it's even the same argument order for git-clone.
Pretty much all command lines use "source destination" order.
Why is 'ln' confusing? Because people think of "linking" in a backwards way, it seems that if you're creating a link from A -> B, A is the source and B is the destination. But that's not the meaning of "source destination" that command lines expect
mv B A
A is the new B cp B A
A is the new B, but B is still there ln -s B A
A is the new B, except it's just a link, and yes, B is still there.B is the source, A is the destination. B is the source of the data, A is the destination for that data; the command will create 'A' (or modify it), that's why it's the destination.
For the link itself, B is the destination, but for the operation of creating the link, B is the source, and that's the meaning that's consistent with all other commands.