64

I have used ln to write symbolic links for years but I still get the order of parameters the wrong away around.

This usually has me writing:

ln -s a b

and then looking at the output to remind myself.

I always imagine to be a -> b as I read it when it's actually the opposite b -> a. This feels counter-intuitive so I find that I'm always second-guessing myself.

Does anyone have any tips to help me remember the correct order?

  • 11
    sometimes it help to say it outloud when you type it in "symbolic link to a, and call it b" – jsotola Sep 15 at 1:13
  • 2
    You create the second parameter just like with cp, and you create the link. But if you get it the wrong way, no worries, because you cannot overwrite an existing file or symlink with a new link. – sudodus Sep 15 at 14:33
  • 1
    Related: Direction of a symlink – G-Man Sep 15 at 23:25
  • 1
    Think of it as a "bad guy's alias." He is always referred to by his real name first, then his aliases. Ex: Tony Baloney a.k.a. Oscar Meyer. Or in the case of your link, ln -s a b means "File-a is also known as File-b". – Scottie H Sep 16 at 15:26
  • 1
    ln source target. Same as cp source target, mv source target; ... – user207421 Sep 17 at 9:44

14 Answers 14

40

I use the following: ln has a one-argument form (2nd form listed in the manpage) in which only the target is required (because how could ln work at all without knowing the target) and ln creates the link in the current directory. The two-argument form is an addition to the one-argument form, thus the target is always the first argument.

  • 3
    Note that the form with no destination/target path is an extension to the POSIX specification of ln. – Kusalananda Sep 15 at 18:18
  • 1
    @kusa: did you see the 1971 manual in my answer with the one-argument form? How can it be an extension to posix if it was there in 1971? --- "If name2 is given, the link has that name" – user370539 Sep 15 at 19:41
  • @S.P. I'm not sure I understand what you mean. Are you saying that a historical implementation somehow trumps the current POSIX standard? – Kusalananda Sep 15 at 20:01
  • 1
    I also see. Different names, same args, at least. I had no idea gnu is the only one with these arg names. – user370539 Sep 15 at 21:46
  • 2
    There were a lot of good answers here (expecially the rhyme by @loa_in_) but I'm going to go with this one. Stating that the order of parameters is consistent (ignoring -t) then it feels almost like a proof. "ln creates the link in the current directory. The two-argument form is an addition to the one-argument form and therefore the target is always the first argument". Because it makes sense that this would be the case when considering the second form, I think this will help me remember. – Zhro Sep 15 at 23:55
85

I go by "ln is like cp. The 'source' needs to come first."

  • 20
    ...and like mv. mv, cp and ln all take an existing file as first argument, and the intended destination file or directory name as second argument. – Hans-Martin Mosner Sep 15 at 7:44
  • 7
    It's a shame that memcpy, strcpy etc. work the other way around. – Arkadiusz Drabczyk Sep 15 at 13:53
  • 6
    @Hans-MartinMosner, except that when you create a symbolic link, it doesn't have to be an existing file... – ilkkachu Sep 15 at 15:35
  • 1
    @ilkkachu You're right. No rule without exception :-) – Hans-Martin Mosner Sep 15 at 16:03
  • 1
    @ArkadiuszDrabczyk On the other hand, something like memcpy(dest,src,n); maps very well to dest = src;. In other words, set (the first n bytes of) dest equal to (the first n bytes of) src. – a CVn Sep 17 at 12:39
10

Most Unices document the ln command as

ln source target

(I'm omitting options etc. here)

Examples:

  • The POSIX standard

    ln [-fs] [-L|-P] source_file target_file
    
  • OpenBSD:

    ln [-fhLnPs] source [target]
    
  • NetBSD and FreeBSD

    ln [-L | -P | -s [-F]] [-f | -iw] [-hnv] source_file [target_file]
    
  • macOS

    ln [-Ffhinsv] source_file [target_file]
    
  • Solaris

    /usr/bin/ln [-fns] source_file [target]
    
  • AIX

    ln [ -f | -n ] [ -s ] SourceFile [ TargetFile ]
    

The GNU ln manual calls the source target and the target linkname.

Ignoring the GNU choice of words, the ln utility follows the same sort of semantics as e.g. mv and cp in that the target is what is created from the source.

Therefore,

ln -s a b

would create the symbolic link b pointing to a.

Note also that when creating symbolic links, the source is simply a string representing what the symbolic link should point at. There is usually no check made to validate that it points to anything useful:

$ ln -s "hello world" README.txt
$ ls -l
total 0
lrwxr-xr-x  1 kk  wheel  11 Sep 15 11:39 README.txt -> hello world
  • 5
    I fully blame the GNU documentation for the fact that people get this wrong at all. Their wording is understandable in hindsight but objectively confusing. – Konrad Rudolph Sep 15 at 12:11
  • 6
    @KonradRudolph, On the contrary, the GNU wording seems spot on to me. The utility creates a link with some name, pointing to somewhere. "Link name" is kinda obvious, and "target" is a perfectly good description for something that is pointed to. As an anecdote, I still have to sometimes think which way ln -s a b works, and that has nothing to do with the GNU wording, since I don't think I've ever looked at the phrasing in the man page. :D (It's easier to just run ln -si a b when not sure, it'll complain if b already exists.) – ilkkachu Sep 15 at 17:22
  • 1
    @KonradRudolph, though technically, calling it "target" in the case of a hard link is wrong, since it's not the existing name but the inode that's the actual target. I wonder if the GNU folks thought that a common user shouldn't have to think of it in that much detail. – ilkkachu Sep 15 at 17:24
  • It's interesting to point out, as mentioned in the comments of @gary's answer, that the target is not optional in the POSIX standard. – Zhro Sep 15 at 23:42
  • @kusa: with "ln -s A B --- copy only the file's name to B " I have adopted your interpretation in a slightly changed context. I can even agree with your radical "hello world" example. "Only the file's name' IS a string. Just want to signal to you that I edited a bit and added a lot. – user370539 Sep 16 at 12:00
7

In case this helps anyone: I've gotten used to thinking of it as "ln what where", which helps me remember that the first argument ("what") is the existing file, the second ("where") is the place to put (a link to) it. As opposed to the reasoning in most of the other answers, this is nothing more than a pithy phrase that I can mentally recite to myself as I'm typing a command, which serves as a memory aid. This probably won't be useful to everyone but I suspect that it will help some people.

It helps that the other standard file manipulation commands use the same convention, so I can do the same for cp and mv.

  • 4
    I'm curious to get some idea of why this was downvoted. There's not much here that could be wrong - did I mix up the order or something? – David Z Sep 15 at 14:04
  • I personally think that "ln what where" is still not unambiguous without the explanation: what could either be "what is the link pointing linking at?" (correct) or "what is linking to something?" (wrong). Same with where: "where is the link pointing to?" (wrong) or "where should the link be created" (correct). So this does not necessarily help that much if you are second-guessing yourself. Remembering cp and mv should help though. – 125_m_125 Sep 16 at 17:00
  • We all expect a UNIX command to include its file arguments after other kinds of argument (like grep does, for exmaple). ln creates a file of a certain type with a given contents. That the filesystem does something special and we usually put the path to some source file in it is incidental to ln. For exmaple, I could write a text editor which stored the contents of its first line in a symlink called 1, etc. This would be daft but it emphasizes that ln creates some kind of file with some text contents, nothing more or less, and makes the argument order seem logical. – Dannie Sep 16 at 17:19
  • @125_m_125 The alternate interpretation you presented doesn't make much sense to me, but that's okay; this memory aid isn't for everyone. – David Z Sep 16 at 18:20
6

I recently heard a great way to remember this particular thing: a rhyme

Something old, something new,

something borrowed, something blue,

and a sixpence in her shoe.

The first verse is what the arguments of ln are: something old followed by a name of the new directory entry.

3
NAME    ln -- make a link
SYNOPSIS    ln name1[ name2 ]
DESCRIPTION ln creates a link to an existing file name1. 
            If name2 is given, the link has that name; 

From 1971 Unix First Edition Manuals.

There is a second, simple, syntax form.


edit: I put FILE or FILENAME instead of TARGET --- see comments etc. see also very long addition at the bottom, addressing the iceberg, hard and soft of ln, not just the tip of it.


So GNU ln has this:

ln [opt] FILENAME

In the 2nd form, create a link to FILENAME in the current directory.

where you don't need the link name. After ln -s /usr/lib/modules you get a

modules -> /usr/lib/modules

with the same name as FILENAME ("target" or "source"), right where you are. No choice, no confusion.

Now if you are more demanding and want the link created under another name and/or somewhere else, you add that wish as name or path. The real target comes first, the extra fantasy new link name second.


Or you say: "I know this arrow notation in ls -l for links. I don't have an arrow in the shell to show the direction of my link. So I have to turn it around."

You create it in one direction, so you can use it in the other.

(END OF ANSWER-THE-QUESTION PART)


On another level, the word "link" itself carries a deep hidden double meaning. Symbolic links came later, so in the early days a link was just a link. There was no soft and hard, no -s option. And now I even use the source-target symbolism:

mv    A B   --- move the whole file to B (dir or new name)
cp    A B   --- copy whole file (mv and cp are "the same" here)    
ln    A B   --- copy whole file MINUS data blocks (=copy only inode and name), and increase "link count" for track keeping

At this stage, there are links, but no hard and soft, and ls -l does not show arrows, because there is no direction in a (hard) link. A "link" at that stage of unix evolution meant that filename "B" (directory entry "B") in the filesystem points to the same inode as filename "A" is pointing to.

Files A and B are "linked" together, because they share the same blocks. So now with every rm, the kernel has to check: do I delete/free this file's blocks on the disk, or is there another file linked to the same blocks? For that, a link counter is used.

Say you want to keep a big file on /tmp grom being deleted and do ln /tmp/bigfile. Now you have a large bigfile in your working dir. After cleaning /tmp and rmoving the "original", you happily go on using the same data blocks. You don't get a dead or dangling link, you have a normal file. Pointing to no file but only filesystem blocks as every dir entry does. Only now "cleaning" /tmp is not as effecitve as it was. It looks empty, and it is, but the blocks on the partition don't get freed.

Even though a hard link does not cost space itself as cp does, indirectly, it can.

Adding ln -s to the sequence above:

ln -s A B   --- copy only the file's name to "B"   

Now "B", the soft link, only has a string with a pathname. This is "soft" info. Technically "A" and "B" are unrelated. But still B is a "link" in the new sense that you can use that stored pathname as a shortcut to "A". Now it is "a link to A" (period) and not "linked with file A's inode"

Both kind of links can confuse not only humans but also the kernel/fs. The 1971 man page notes: "BUGS: links get backuped twice, and restored as seperate files with separate inodes."

Hard links to directories (rare/not allowed) can easily lead to a clog.

Soft links to directories (very common) can lead to eternal loops - has to be recognized by utilities / kernel.

Practical example in bash

Starting with a regular file "F"...

ln F Fhard

...makes Fhard the same size as F, but they BOTH appear now in a dark red WITHOUT arrows in ls -l --color. Because of stat showing "Links: 2" in connection with "Inode: xyz". Hard linking F turns F itself into a hard link. Both are/stay filetype "regular file". But both have an inode with a link count above 1.

   ln -s F Fsoft

...makes a tiny "unregular" file "Fsoft" with filetype "symbolic link" --- even more space saving than an empty dir. A ls -l shows nothing special for "F". For Fsoft, the shown size is 1 byte as the string is 'F', and Fsoft -> F is displayed as name. No need to colorize a soft link to recognize one. Because in the short form ls -F you get a coiled chain @ appended: Fsoft@

With ls -l it looks like this:

-rw-r--r-- 2 root root 6070340 Sep 16 16:28 F
-rw-r--r-- 2 root root 6070340 Sep 16 16:28 Fhard
lrwxrwxrwx 1 root root       1 Sep 16 16:31 Fsoft -> F

Fhard has F's size and type.

Fsoft has F's name and F's name's length as size, and a different file type.

Short ls -sF:

5932 F    5932 Fhard     0 Fsoft@

adding --block-size=1 does not yield same sizes either. Fsoft has size "one byte, zero blocks". F and Fhard deviate in parallel:

6074368 F  6074368 Fhard    0 Fsoft@

To see whether Fsoft is dangling or not, ls lets you use colors.

ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file
2

It is really helpful to remember that the name of the link is optional. If it is not given, the basename of the link target is used.

ln -s /path/to/file1 file1

is identical to dropping the link name completely:

ln -s /path/to/file1

This would not make any sense if the link target was mentioned last.

1

Just think Unix -> AT&T -> destination on right:

mov %eax, %ebx  ;; AT&T style assembler syntax: %ebx register gets value of %ecx

mv foo bar    ;; foo renamed to bar

cp foo bar    ;; contents of foo go to bar

foo | bar     ;; data moves left to right in pipeline

ln abc def    ;; link to abc installed as def
  • "cp foo bar" means "to bar". "ln abc def" means "to abc". If you had kept the symbols: "to foo". That is exactly the problem. – user370539 Sep 18 at 8:37
  • @user370539 That is ismply not true; after ln abc def, abc and def are the same object; they are indistinguishable. Moreover, the operation has no effect on abc, other than increasing its link count. The destination is def. A pointer to the object is newly installed in the def location. – Kaz Sep 18 at 17:41
  • @user370539 If the link is symbolic, then ln -s abc def means that the content abc is written to location def. abc doesn't even have to resolve to anything; it can be a dangling link. – Kaz Sep 18 at 17:43
  • Your comment is exactly... wrong. It should be the other way around. – rexkogitans yesterday
  • @rexkogitans My point is that it's consistent. If the order is "wrong" and should be reversed, then it should be for all those commands: mv dest src, ln [ -s ] dest src, cp dest src, ... – Kaz 11 hours ago
0

Personally, I prefer to avoid remembering X, in favour of knowing where to look for X when I need it. I'm also a fan of the "better safe than sorry" attitude so I always like to check carefully what I'm writing, especially as root.

In this case, the answer is literally in the first lines of the manpage:

   ln [OPTION]... [-T] TARGET LINK_NAME
   (...)
   In the 1st form, create a link to TARGET with the name LINK_NAME.

I wouldn't have suggested it if it required to delve in the manpage, but since it's right at the beginning, IMHO it's worth the 3 seconds it takes to type man ln and quit.

-1

Similar to cp, which I mentally read as “copy this to that”, I read ln commands as “link this to that”.

  • 2
    This is very similar to the top-rated answer. – Michael Sep 16 at 18:37
  • So "ln -s A B' links A to B? Is it now A -> B or B -> A ? I think most have not even passed the first stage of confusion. They say it is simple, but it is just wrong. – user370539 Sep 17 at 18:28
-2

This is how I remember it: Forget the target. In other words, if I am in dir1 and want to create a symlink here to file1 that exists in /some/other/dir/, I would just do:

ln -s /some/other/dir/file1

You will get a symlink called file1 in dir1 that points to /some/other/dir/file1. From the man page for ln:

ln [OPTION]... TARGET (2nd form) ... In the 2nd form, create a link to TARGET in the current directory.

Just keep in mind that this work only if you want the symlink to have the same name as the target (which most likely is the case).

  • Can someone please explain why this was downvoted? I just copy-pasted from the man page (and accordingly attributed). It will help others to understand how to post on SE. Thanks. – Hopping Bunny Sep 18 at 5:35
  • i can explain: it is a cultural clash. Don't worry. Check the other answers, comments... – user370539 Sep 18 at 7:13
-3

I'd like to expand on @gary's answer.

In addition to his anwer: the ln command can accept arbitrary number of arguments, so that you can create multiple symlinks in one invocation (which is handy when you need it).

  1. With that knowledge, when you encounter ln -s foo bar baz, what's the most logical explanation which arguments means what?
  2. With the answer to #1, when you encounter ln -s foo bar, what's the most logical explanation which arguments means what?
  • 1
    If you have an addition to gary's answer, please suggest it as an edit. As-is, your two trailing (hypothetical?) questions make this "Answer" look more like a second question. – Jeff Schaller Sep 17 at 18:19
-3

Imagine a version of ln which allowed you to create multiple (symbolic) links in one command.

Synopsis: ln -s TARGET NEW_LINK...
Example: ln -s target_file  new_link_1  new_link_2  new_link_3

It wouldn't make any since to reverse that, since a symlink can only point to one TARGET at a time and the normal command line convention is to put the repeating part at the end of the command line, e.g. grep PAT [FILE]...

-6

"ls shows a -> b so ln a b"

Just remember that this is wrong.

  • 6
    I always remember "something-something is always wrong". But which way is wrong? That's the problem. The problem then becomes my second-guessing myself even when I get it right. Because I can't actually recall the correct order! – Zhro Sep 15 at 2:56
  • I think I understand what you mean: the output of ls -l: link -> target can confuse your idea of how to set up the ln command line. But I am afraid that it will not help much. – sudodus Sep 15 at 14:22

protected by Kusalananda Sep 18 at 5:34

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.