On the list of things I always Google, is how to create a symbolic link under Linux. I just can't figure out a way to remember what comes first; the source or the destination. The man pages add to the confusion by calling the "source" the target. So, the rule of thumb I now follow is cp or mv semantics.
Here's how I finally memorized it: ln has a 1-file-argument invocation, so ln -s ../../a_fine_file will create a symbolic link to that file under the current directory and under the "a_fine_file" file name. The single argument case has to have the file you want to link to as input. That generalizes nicely as the 2-file-argument invocation maintaining the logic.
A guy in the office always remembers it as remembering that wedding saying - something old, something new, something borrowed, something blue. Whenever he did a symlink he would always say out loud something old, something new, ... That has stuck with me as well for all these years so I've never needed to figure out which was which, I always just knew it.
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).
Interesting. Thanks, that's helpful. It's also a necessary approach for using relative paths as targets when you refer to the current directory to add the link in.
I think of it like `cp`. Source to destination, where destination is the soft link. so it's like copying a file somewhere but instead of a copy you're making a link
This. "I want something here that points to there" is how I always think about it. That's why "link" on my boxes is mapped to "ln -s" with the arguments swapped :)
> I think of it like `cp`. Source to destination, where destination is the soft 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.
If it was a hard link, I suppose my way of thinking about it would make more sense, since all hard links are as valid, pretty much the same. That is, after running
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.c
This 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?
I do this as well, but it only works if I don't think about it. If I start thinking about it, I begin second guessing myself on whether I got it right and end up having to look it up.
I always think of links as pointing from source to destination. Your way would break that intuition for me. It would be the source of the address and the destination for the address to be copied to.
I understand fully; that’s also how I thought of it for years and why I couldn’t ever remember it. But if you think about it like copying a file it’s easier to remember. And it is like copying a file— it’s copying a reference to a file.
Given the number of things that use different source vs destination with the same type, I just have trained myself to always look it up, even if I am 99% sure I remembered it correctly, because holy shit when you get it wrong sometimes it's bad.
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...
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.
Two minor points: They are both real files. The symlink may be created first.
"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.
Reading the man page instead of Googling this will make you a better engineer, and it will also cost more of your time while you figure out what the man page is trying to say. This knowledge may save you time later, if you use it again, or not. So the advice I would give is, never Google if the answer can be found in the man page. Unless it's a tool you're unlikely to ever use again, of course.
Man pages are so insufferably long and mostly irrelevant though. It's come up on HN before, I think, how if you're ever looking for anything specific like commonly used arguments and common usages, it's a complete waste of time to go through an entire man page.
Except that, if you think about it, every sentence in a well-written man page was put there by an absolute expert in the tool who thought you might need to know it. If you want to master your tools, it's absolutely not a waste of time to read the friendly manual. When you use a system professionally every day and refuse to read the manuals because it takes too long, and you're in way too much of a hurry, you're only hurting yourself in the long run.
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.
Well, no. Even if I read the damn thing, there are tens of tools I use day to day. I'm not going to remember any of it. It doesn't matter how much of an expert the author was if it's not structured in a useful way. And I've read enough fucking man pages. I've retained zero except for maybe what I ended up using. If I used it more than once. Maybe. Man pages don't tell you shit. They tell you everything and you still need to parse, interpret and analyze it because it's so ridiculously dense and there's never any guidance on actual real-world usage. Theoretically they're useful, realistically, they completely ignore everything about how human beings function. They're not written for people.
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.
Reading, interpreting, and using dense technical documentation is a skill, just like reading maths. If you don't get anything out of it, maybe this is a skill you are presently lacking and something you should improve. Taking notes on what you are doing and reviewing your initial guesses, resources consulted, and eventual solutions may help you consolidate this ad-hoc knowledge into understanding.
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.
You're insufferable like every other Linux elitist out there. You realize being polite while being an arrogant prick doesn't change how much of an asshole you are being? I hate this kind of bullshit and I'm tired of it. And I'll get warned because I'm the one getting mad over it. Fuck this shit.
I know it sucks when your environment sucks and your tools suck and people tell you your habits suck too. I can tell you're frustrated by your tone in this thread even before I told you that you may lack the skill of slowing down enough to read technical documentation. So, you're right. I'm telling you to be better and try harder, and I don't even know your situation! Maybe that does make me an asshole. Certainly most people higher on "agreeableness" than I am wouldn't say those mean things.
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.
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.
It isn't just like `cp`, on some systems `ln` is just a symlink to `cp`! `cp -s` does the same thing as `ln -s`, although the other flags are generally different.
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'.
That's because with zip (and tar, and other archivers) you can have multiple items to move to a destination archive.
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.
I think 'ln' as a tool which creates a symlink. And symlink is a new object, a new kind-of file. So it must be the last argument. The source is just an attribute of that symlink "file" holding the path it points to. If I want to overwrite an existing symlink "file", I simply add -f meaning force-overwrite-if-the-symlink-file-already-exists.
I couldn't remember also.
The way I finay did it was to memorize 'ln -s -T' -T stands for target that way... I know the next thing must be the target then the source.
If you google/duckduck go something more than once, I think it should be put into documentation. I have one central org file where I keep that majority of my one off questions about a tool, and these days I look there often first before man or info because I have condensed the information into something faster to parse for me.
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.
I search (duck duck go) for this constantly. For a couple of days last week I remembered it, but it’s always helpful to check. Some day I should see what happens if I get it backwards. Probably it will say no and that’s it. If that’s true then I can just try until it works!
I remember it by first remembering that it is possible to not provide the destination (ln /.../file) to create a symlink with exactly the same name in the current directory. So it has only 1 required argument which always has to be first.
That is the symlink target, not the ln target, which is exactly why the "target" nomenclature is confusing. Also note that not every "ln" has a "--help" or uses that help message as the output. For example, try on OS X `/bin/ln -h`.
Yes, it would be platform specific as the OSX ln command would not be the same program as the GNU coreutils ln program.
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.
I wasn't speaking specifically about GNU. Note though that even there you see a --target-directory, -t, -T flags that make literally no sense anymore once GNU reversed the meaning of the term.
I totally get that you don't remember what goes first, it happens to me with tons of commands... but googling it? Why don't you just execute the command and see if it worked?
Haha, glad to see I'm not the only one who struggled with remembering this. I always refered to a task in a fabfile to remember. +1 for "follow cp or mv semantics"
There are some clever tips here how to remember. Ages ago I struggled too so for half a day I just kept repeating the words "ln target linkname" in my head. Anyone else?
I feel like a lot of this stuff is rote memorization that we shouldn't be so eager to demonize. The medical profession has you memorizing effectively random shit for years and that's fine. But in our industry, we think we should just magically remember stuff we enter once in a blue moon, and if not, who cares, just Google for it. It bothers me. And it's something I've increasingly turned to flash cards for. I'm tired of googling that command I used once 3 months ago but would be insanely useful right now.
The infuriating thing is that Windows' mklink does it the other way around... link, then target. It took me years to stop RTFM every single time I'd user mklink/ln
I have remembered the order of arguments since I figured out that the second argument is optional. So the link name is of course optional, not the original file's one.
I don't understand where the confusion is with scp. It's just like cp, except you have a syntax for making some of the arguments remote. It doesn't change the order, it always does semantically the same thing of moving something(s) somewhere.
This is not to criticize - we all have places our mental models break down unexpectedly. I'm just interested in how that's happening.
I no longer have issues with tar since I found out that most systems I use don't need the compression format anymore, and are happy to figure it out themselves. Not sure if it works with compressing or not (I generally use 7z or zip), but you can just `tar -x[v]f` on anything, regardless of file extension, and tar will extract anything it supports.