The problem with "from" and "to" is - which is the from and which is the to?
Is 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)
Exactly! The rule is for that commands of two letters in length (cp, ln, mv) the file on the end is the one that gets created. For commands of three letters in length (tar, zip) the file that gets created is the first one. And then there's the exceptions that prove the rule like scp and ssh.
Exactly. Why the GP's comment is currently at +33 when all it does is restate the main point of the story in a confusing way (by introducing from/to into the mix) is beyond me.
Probably because most of the people upvoting him didn't bother to read the story.
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:
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.
I used to just cheat. I normally cd-ed to the directory I wanted the link in then just let the name of the link be the name of the file, so I didn't need a destination file name, just ln -s source_file
As someone who always had that problem, I think it's because I always mentally picture a command as saying "do <action> from <arg0> to <arg1>", ie, "copy this file to that file". But this construct doesn't hold up for linking, so I just have to remember it arbitrarily by remembering cp. function(src, dest) just generally seems to be the unofficial "right way" of ordering things.
My god, this thing always keeps biting me. It seems so obvious now with that cp-mnemonic. But it makes me wonder, why does everyone do it wrong in the first place?
My theory is that we're used to see symlinks as part of the "ls -l" output, which lists the link name first, and then the target. Later, we want to create symlinks as we're used to see them (linkname -> target).
Does anyone know why C calls like 'strcpy' and 'strcat' are the opposite of this?
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.
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'.
Which is really the odd ball. In a left-to-right language, it's sort of bizarre that we don't write `4 = x' since the rvalue tends to be the more complicated part of the expression.
The curious bit is, AT&T assembly syntax does follow this convention so you'll see something like `mov $5, ax'.
It's similar to all the file I/O functions that always have the file descriptor first (fprintf etc). These are the heart of Unix. Remember the Unix philosophy: Everything is a file.*
* for a slightly smaller definition of everything than in Plan9
This is a crime against usability IMO. Another comment mentioned that tar takes arguments as "target source" rather than "source target".
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?
And sometimes doorknobs, but those are abstract enough you wouldn't expect them to behave the same. Unless you're talking about screwing the dial itself clean off.
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).
Cars generally still do have backwards nuts on the LHS. Something about vibration and direction of turn. Some of the other bolts on the LHS can be that way too.
Same with some of the LP gas cylinders I have encountered here in Aus.
I have heard that other manufacturers originally starting using reverse-thread propane fittings to work around a 1896 Primus patent, and the situation has simply persisted.
The reason strcat, strcpy have the destination first is because of the need to support a variable number of arguments. By definition, if the number of arguments is variable, they must be at the end. So if you think of sprintf for instance, the destination has to be first. Now, to be consistent, strcat has to behave the same and have the destination first as well, although it doesn't have a variable number of arguments.
I'm pretty sure strcpy et al pre-date the introduction of varargs. Besides, there's no reason the format string couldn't be the last argument of printf, except the specific technical detail that C requires at least one mandatory argument in any variadic function (the variable's address is used to locate the optional arguments in the stack.)
On a machine's runtime stack, there is no indication of how many parameters were passed to the function (at least on x86). C functions must use one of the mandatory arguments to determine how many arguments were pushed on the stack. In the case of the printf-family of functions, it's the number of format specifiers, e.g., "%d".
Someone once said to "What you have, then what you want" which made ALL of these easier to remember for me. In the case of strcat/cpy I think it still follows: I have an empty string 'target' and I'd like it to be 'source'.
C calls are trying to mirror the assignment statement in the programming language:
target := source
"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.
The real/imaginary concept is exactly what I use too. I sort of recall being able to use the real/imaginary concept with other Unix commands as well, but I can't recall which ones off the top of my head.
My mneumonic is that in "ln" the "n" comes second, and n is for "name" so the name of the symlink comes second. But I still have to think about it every time...
You can create multiple links with the original names at once with commands like:
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".
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!
My mnemonic for this is to remember that the link name is optional. When you specify only one argument the link name is the base name of the target (in the current working directory). Therefore the link name must be the second argument.
It's the same argument order for mv and cp, also the same for rsync and scp
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.
126 comments
[ 3.7 ms ] story [ 193 ms ] thread$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.
Is 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! :)
flip 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:
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.
mklink link_to link_from
EDIT: formatting.
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>"
I had a friend who gave up and made an alias that sorted out which of the arguments existed and did The Right Thing.
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'.
* 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.
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:
For "mv A B"
I've no problem saying either
orhttp://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.
Intel:
mov bx, 100
AT&T:
mov $100, %bx
http://en.wikipedia.org/wiki/X86_assembly_language#Syntax
"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.
strcat, then, is for symmetry with strcpy.
http://en.wikipedia.org/wiki/Complex_number
ln -s source fakename
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".
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!
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
A is the new B A is the new B, but B is still there 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.