93

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?

15
  • 13
    sometimes it help to say it outloud when you type it in "symbolic link to a, and call it b"
    – jsotola
    Commented Sep 15, 2019 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
    Commented Sep 15, 2019 at 14:33
  • 1
    Related: Direction of a symlink Commented Sep 15, 2019 at 23:25
  • 3
    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
    Commented Sep 16, 2019 at 15:26
  • 7
    ln source target. Same as cp source target, mv source target; ...
    – user207421
    Commented Sep 17, 2019 at 9:44

13 Answers 13

109

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

9
  • 27
    ...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. Commented Sep 15, 2019 at 7:44
  • 7
    It's a shame that memcpy, strcpy etc. work the other way around. Commented Sep 15, 2019 at 13:53
  • 6
    @Hans-MartinMosner, except that when you create a symbolic link, it doesn't have to be an existing file...
    – ilkkachu
    Commented Sep 15, 2019 at 15:35
  • 1
    @ilkkachu You're right. No rule without exception :-) Commented Sep 15, 2019 at 16:03
  • 2
    @s1lv3r the arguments to tar are not positional. The path to the archive file is the parameter to the f(ile) option.
    – OrangeDog
    Commented Sep 17, 2019 at 15:34
48

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.

10
  • 3
    Note that the form with no destination/target path is an extension to the POSIX specification of ln.
    – Kusalananda
    Commented Sep 15, 2019 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
    Commented Sep 15, 2019 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
    Commented Sep 15, 2019 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
    Commented Sep 15, 2019 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
    Commented Sep 15, 2019 at 23:55
14

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 is the odd one out and calls the source target and the target linkname.

Ignoring the GNU choice of words, the ln utility follows the same 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. Or in other words, b is the target of the operation that creates a symbolic link using a as the source.

Note 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

A personal thought about GNU's choice to use "target" and "link name" rather than "source" followed by "target":

It may seem obvious that the second argument, the thing that is created, should be the "link name" and that the first argument, the target of the link, is "target". However, that's only true when you use the link.

When you create the link, which is what you're doing with ln, the second argument, the thing that is created, is the "target" of the ln operation, and it's created using the first argument, the "source".

This, together with the analogous "source"->"target" ordering of arguments to other basic tools, makes the non-GNU documentation for ln seem more natural.

7
  • 7
    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. Commented Sep 15, 2019 at 12:11
  • 8
    @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
    Commented Sep 15, 2019 at 17:22
  • 2
    @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
    Commented Sep 15, 2019 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
    Commented Sep 15, 2019 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
    Commented Sep 16, 2019 at 12:00
12

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.

1
  • this should be the mnemonic. It's very difficult to remember what's the source and what's the target. When I'm thinking about pointers then the target is what is being pointed to by the source (i.e. pointer) so it's not correct in this case
    – phuclv
    Commented Apr 19 at 7:24
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.

6
  • 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
    Commented Sep 15, 2019 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
    Commented Sep 16, 2019 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
    Commented Sep 16, 2019 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
    Commented Sep 16, 2019 at 18:20
  • @DavidZ, well I didn't downvote you, but I read it as "what link, and where does it point" which is obviously not what you meant. ln follows the mv syntax more or less. From [usually] existing to non-existing. Commented Dec 22, 2020 at 19:17
4
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.


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 fancy 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 from being deleted and do ln /tmp/bigfile. Now you have a large bigfile in your working dir. After cleaning /tmp and removing 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 effectve 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, it can indirectly.

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 backed up twice, and restored as separate 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 - these have 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
0
0

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

2
  • 2
    This is very similar to the top-rated answer. Commented Sep 16, 2019 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
    Commented Sep 17, 2019 at 18:28
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
  • Only the GNU man page for ln document it as "[target] [linkName]". All other flavors document it as "[source] [target]". The problem is "target" is ambiguous. (the GNU man page makes the most sense IMHO)
    – Michael
    Commented Jun 24, 2023 at 23:59
-1

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

2
  • 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. Commented Sep 18, 2019 at 5:35
  • 1
    i can explain: it is a cultural clash. Don't worry. Check the other answers, comments...
    – user370539
    Commented Sep 18, 2019 at 7:13
-2

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

-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
  • 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
    Commented Sep 17, 2019 at 18:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .