Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

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.


Ha! My trick is to

  ln -s a b
then look at the link with ls -l, then remove my garbage! Your way is much better.


I just do it the one way, get the error that the destination already exists, then swap them.


I think most people just feel this is risky. What if you overwrite your file? If it was a cp command, that's what would happen.


Me too, I was starting to think I was the crazy one after reading the other comments :)


Except if b is a directory, then ln -s a b will create a symlink at b/a which points to a.


Yup, exactly. I always use the form:

  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).


Sounds like you're making bold assumptions about people's beliefs about whether the extra argument would go before or after the existing argument :)


That's how I memorized it too! Really struggled with it until I started thinking of it that way.


What do you all use symbolic links for so much that you would need to memorize it?


Thank you, this is really helpful.


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 use a similar rule for those git commands that either take one or two branch names. The latter one must obviously be the current branch by default.


and now I've just memorized it myself. Thanks!


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


Same here. After adopting this approach, I haven't had to look it up since.

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.


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?


how about like this:

# cp [existing-thing] [new-thing]

# mv [existing-thing] [new-thing]

# ln -s [existing-thing] [new-thing]


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.


> how to create a symbolic link under Linux. I just can't figure out a way to remember what comes first

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"


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.


Remember it like this: just as in cp, the file that already exists comes first, the file/link we are creating now comes second.


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.


Try taking the command a step back with hardlinks: ln source dest

The association with cp makes a lot more sense then. This is how I learned it.


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...


Intel assembly: mov dest, src

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.


at least arm and mips both match x86 (right? unless I forgot. probably I forgot, it's been over a decade)


Both of the parent's examples were in x86, intel and AT&T are only syntaxes for the same thing.


Well two differing conventions above are both for x86, so you can't "match x86".


I've heard that C's src/dest parameter order is supposed to match assignment.


What came first: the file or the symlink? Of course the real file came first!

Mnemnic that helps me: IN SYMLINKS, REAL FIRST!

ln -s REAL_FILE link_name


I know of two different ways to remember:

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.


This. Same as mv AND cp.


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.


I used to Google that a lot. But now I make an analogy with "cp", the second argument being the file that is been created (the simlink in this case)


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.

Good luck!


This is how I remembered it: Look, it's just like ''cp'', except you're making a symlink, not a copy.


Same here.

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.


There's a reason for the saying "the master has forgotten more than the journeyman has ever learned." :P


"it fees up more space for other more interesting stuff"

I see you take a similar approach to spelling


Your punctuation choices are also executive level.


Yep.


I believe it's a specific POSIX standard that CLI tools are always in the same order: source -> destination[1]

ln, cp, mv, most everything will always follow this pattern.

https://www.gnu.org/software/swbis/sw.html#o-Explicit-File-D...


It is like `cp`.


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.


You might like the tldr program:

$ 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


This is used to really confuse me too, but now I can't remember why, because everything's the same:

  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'.


I think "zip" breaks this rule.


Zip is a DOS tool, so I’m not so surprised it’s not following Unix conventions...


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.


The `...` in my post above was to indicate that.

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'.


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.


Busybox's ln --help is straight to the point

  Usage: ln [OPTIONS] TARGET... LINK|DIR
  Create a link LINK or DIR/TARGET to the specified TARGET(s)


I always type ln -sT ..., which then helps me remember which one is the target of the link.


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.


Well, you're linking TO something and not FROM something so target seems more accurate(they are essentially pointers).

I'm honestly surprised about the help confusion though:

ln --help Usage: ln [OPTION]... [-T] TARGET LINK_NAME (1st form)


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.


If "target" is used to mean two different things in the same context, it is going to confuse people! This is why naming things is hard!


In GNU coreutils ln help and man page it only ever uses TARGET to refer to the link target?


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.


Honestly I gave up memorizing when I realized you can just omit the second parameter.

    ln -s /the/real/thing
will create a symlink in your current directory with the same name.


About 15 years ago a colleague of mine at IBM had the following on their board.

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.


I pretend that '-s' stands for "source", not "symbolic"; and source file follows -s(ource) option. IOW `ln -s A B' is `link source A to B'.


Thinking like this, it fits the pattern of other coreutils tools:

    $ mv existing_path new_path
    $ cp existing_path new_path
    $ ln existing_path new_path


I remember it as FROM source, TO target, so the real file comes first


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.


In the old days there was just 'man ln'


Yes, you don't need to switch to a browser.


I still couldn't do it on the command line, probably cheating, but Midnight Commander shortcut is CTRL-X-S :)


It bothered me as well, my mnemonic became "link to <this target> using <this link name>"


All gnu command line tools are the same in this regard: SOURCE DESTINATION.

    ln -s src dst


I read `ln -s A B` like "link A as B", and it tends to work with most Unix commands.


I found remembering that it's the same as `cp` is what stopped me from continuously googling it.


It finally clicked with me when I read about it as ln -s real fake

Real is always better than fake, real comes first.


Works for typedefs too.


The best way to remember it is that only the first argument is mandatory.


I just search my shell history for that one, because I can never remember either!


For simple shell commands like this, tldr is really handy.

https://tldr.sh


fwiw, I always say outloud in my head "thing that exists first" -- but I did need a mnemonic. Somehow I didn't realize it was just cp semantics.


My memory aid is "link file as linkname".


I'm the same way with scp, I never remember the order and then it changes if you're uploading or downloading.

Also, an obligatory xkcd: https://xkcd.com/1168/


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 find scp really easy. rsync, on the other hand, is like tar to me.


Easy way to remember extracting with tar is "eXtract Zee Files" -xzf.


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.


i've personally given up on this after googling it a dozen times and now i just cd into the target directory first and omit it


link -s this (to) that

This has to exist... but that doesn’t.


Hah, I thought I was the only one!


ln -s actual link

Read it somewhere long time ago, never had to look for it again :)


it is the same as copy first `from` then `to`


I love the man replacement packages like tldr, bro, etc. for exactly these kinds of simple, yet easy to forget incantations.




Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: