ln -s a b
then look at the link with ls -l, then remove my garbage!
Your way is much better. ln -s ../../a_fine_file .
With the added '.' at the end. That way, I can remember to change the period out if I don't want the same name (or if I'm linking in the same directory).The real question I have left: why is this so intuitive for cp, but completely counterintuitive for ln?
I wonder if is because we think of how we would follow the link.
That doesn't make sense to me. The way I think about cp is "copy this, and put it over here". If you think about symlinks that way, you mix it up.
When you say "source to destination, where destination is the soft link", that makes it more confusing for me, because if you consider the symlink that is being created as the "destination" (which at least is the intuitive way to think about it for me, but I suppose it's individual), you actually end up with:
# cp [source] [destination]
# ln -s [destination] [source]
Where "source" is "the new thing that should be created".
Since I seem incapable of getting out of this way of thinking about sources and destinations, my rule of thumb is that when creating a symlink, you always decide where it should point first. Not intuitive perhaps, but this time I've made the mistake so many times it kinda sticks.
ln /some/file /other/file
/some/file and /other/file are hard links. So in this case ln is just copying a hard link, while afaik cp would be copying data, making a hard link pointing to the new data. In userspace? That seems to be what's happening here - https://github.com/openbsd/src/blob/master/bin/cp/utils.cThis is made a bit more confusing by the differences in man pages. For GNU ln, it's shown as ln TARGET LINK_NAME, but for OpenBSD, ln source [target]. But the usage is pretty much the same?
# cp [existing-thing] [new-thing]
# mv [existing-thing] [new-thing]
# ln -s [existing-thing] [new-thing]
Remember it like this: It's the same syntax as "cp". To copy a file you use "cp source dest". It's the same for ln: "ln -s source dest"
The association with cp makes a lot more sense then. This is how I learned it.
softlink dest <- src
file cp src -> dest
std::memcpy dest <- src
java arraycopy src -> dest
golang io.Copy dest <- src
etc etc
I'm only 80% confident I didn't make an error in the above 5 examples...
AT&T assembly: mov src, dest
Whenever I'm debugging at the assembly level I have to just write down the appropriate one on a piece of paper in front of me.
Mnemnic that helps me: IN SYMLINKS, REAL FIRST!
ln -s REAL_FILE link_name
1. Same as mv: `mv REAL_FILE link_name`
2. The second argument is optional. Therefore, the first argument must be the real file, and the second the link name. It does not make sense to omit the real file.
"Source" and "target" are confusing names because the target of the ln command is the file it creates, which is the symlink that points to the source file, which is the "target" of the symlink in an intuitive sense. The mnemonic works because it matches mv and in that case the file that exists must obviously come first. In ln without -s the file also must exist, which makes perfect sense. So it's easy enough to remember if you understand what the ln semantics are and don't get hung up by the source and target jargon.
You're probably going to notice the time you spend reading man pages, when you just! want! to! get! something! done! And that's frustrating. What you're less likely to notice is the next five times you reach for the wrong tool, or have to go hunting around for some bubble-gum-and-twine way to do something, because you didn't previously read the man page that tells you exactly what you needed to know to do it easily and correctly.
Hell, I often find that while the author has managed to cram everything and the kitchen sink into it, there's so much missing from it regarding how a tool works, caveats, whatever. All these things that are crucial to actually understanding the tools you're using beyond what some flag or other does on a surface level.
I've read many man pages, many many times, and if I get nothing out of it, I find it is invariably because I am in a hurry, and I'm probably about to fuck something up. The thing to do is usually to slow down and do it right. Only rarely is the right thing to ask someone else for the solution, or see what some other poorly-informed person on the internet thought, although in an emergency asking for help is almost always the right call.
A huge amount of what man pages don't tell you is general Unix philosophy. Man pages don't tell you the lore around the thing, they describe the implementation. It's up to you to infer the consequences and how it can be used. Man pages don't hide the underlying bones of the system either, and generally assume you're comfortable writing a C program to test a syscall if you're not sure about something. So sure, reading man pages isn't always easy, but neither is getting regular exercise or eating your vegetables.
By the way: I might be a Linux elitist, but nobody's ever called me that. I use OS X in my day job. I've been programming in some capacity for about 30 years. Your mileage may vary. If you take my advice you may hate me for it, but it will almost certainly make you a better developer in the long run. And I don't mind if you think I'm an asshole. I know I'm right, and you probably know I'm right too.
Finally, if we weren't having this interaction in public, I'd be kinder, gentler, and might not say anything at all. But if one other person who hates reading difficult technical material is pushed to overcome that limitation by reading this thread, it's worth it, even if it means making you mad.
And just in case you're still reading, in addition to reading man pages, and taking notes, here are the other things you should be doing:
Preferring textbooks over blog posts and youtube videos to learn a new field.
Reading original research by pioneers in the field, like Turing, Shannon, etc, rather than their main findings rehashed by lesser minds.
Reading source code rather than jumping from documentation to Stack Overflow when something doesn't work.
Reading Knuth on algorithms, Stevens on Unix networking, etc. In other words, read the classics that everyone says you should read but most people don't. Work through the exercises. It's the closest thing to an actual superpower.
Look around for people better than you at all this stuff to help you improve.
Good luck!
Its one of those things that after almost 20 years, I should remember. But it just does not go in.
It becomes interesting when junior programmers are watching how I do something and I end up googl'ing things that they know.
I use the excuse that it fees up more space for other more interesting stuff, a bit like some execs just ware T-shirt and jeans to reduce the number of things to distract them in the morning so that can concentrate on the important things.
I see you take a similar approach to spelling
ln, cp, mv, most everything will always follow this pattern.
https://www.gnu.org/software/swbis/sw.html#o-Explicit-File-D...
$ tldr ln
ln
Creates links to files and directories.
- Create a symbolic link to a file or directory: ln -s path/to/file_or_directory path/to/symlink
- Overwrite an existing symbolic to point to a different file: ln -sf path/to/new_file path/to/symlink
- Create a hard link to a file: ln path/to/file path/to/hardlink
touch <destination...>
$EDITOR <destination...>
mv <current...> <destination>
cp <current...> <destination>
scp <current...> <destination>
mount <current> <destination>
The place you're putting something is last in each case; we can even include everything that doesn't modify its location.All I can think of that breaks the rule is `rm`, `unlink`, and `umount`. But they're hardly gotchas, and they're not reversing arguments they just don't have a 'destination'.
You can also do that with cp and mv if you need to, using `-t`. `cp -t .dotfiles/ .nanorc .bash*`. Generally more useful when you want to move a bunch of files around.
Zip does indeed break the 'rule', but this is not an excuse, cp and mv manage just fine with:
in in in in [...] out
Which is why I said the 'last' rather than 'second'.Right now my main battle is deciding to port docs like this into asciddoc(tor) or keep them in org, both being exported to html5 eventually.
Usage: ln [OPTIONS] TARGET... LINK|DIR
Create a link LINK or DIR/TARGET to the specified TARGET(s)I'm honestly surprised about the help confusion though:
ln --help Usage: ln [OPTION]... [-T] TARGET LINK_NAME (1st form)
For GNU ln at least I don't find it confusing at all particularly considering the only other option is LINK_NAME. I guess YMMV though and it seems kinda pointless to argue whether it is or is not confusing. Perhaps a poll could quantify it.
ln -s /the/real/thing
will create a symlink in your current directory with the same name.ln -s physical virtual
I never forgot it and can see it visually in my mind. You need something physical before you can virtualise it.
$ mv existing_path new_path
$ cp existing_path new_path
$ ln existing_path new_path ln -s src dstReal is always better than fake, real comes first.
Also, an obligatory xkcd: https://xkcd.com/1168/
This is not to criticize - we all have places our mental models break down unexpectedly. I'm just interested in how that's happening.
This has to exist... but that doesn’t.
Read it somewhere long time ago, never had to look for it again :)