33

I'm trying to create a bunch of symbolic links, but I can't figure out why this is working

ln -s /Users/niels/something/foo ~/bin/foo_link 

while this

cd /Users/niels/something ln -s foo ~/bin/foo_link 

is not.

I believe it has something to do with foo_link linking to foo in /Users/niels/bin instead of /Users/niels/something

So the question is, how do I create a symbolic link that points to an absolute path, without actually typing it?

For reference, I am using Mac OS X 10.9 and Zsh.

5 Answers 5

45

The easiest way to link to the current directory as an absolute path, without typing the whole path string would be:

ln -s -- "$(pwd)/foo" ~/bin/foo_link 

or if any component of the current working directory's path is a symlink itself and you want to link to the physical path:

ln -s -- "$(pwd -P)/foo" ~/bin/foo_link 

The target (first) argument for the ln -s command works relative to the symbolic link's location, not your current directory. It helps to know that, essentially, the created symlink (the second argument) simply holds the text you provide for the first argument.

Therefore, if you do the following:

cd some_directory ln -s foo foo_link 

and then move that link around

mv foo_link ../some_other_directory ls -l ../some_other_directory 

you will see that foo_link tries to point to foo in the directory it is residing in. This also works with symbolic links pointing to relative paths. If you do the following:

ln -s ../foo yet_another_link 

and then move yet_another_link to another directory and check where it points to, you'll see that it always points to ../foo. This is the intended behaviour, since many times symbolic links might be part of a directory structure that can reside in various absolute paths.

In your case, when you create the link by typing

ln -s foo ~/bin/foo_link 

foo_link just holds a link to foo, relative to its location. Putting $(pwd) in front of the target argument's name simply adds the current working directory's absolute path, so that the link is created with an absolute target.

6
  • "...helps to imagine that the created symlink simply holds text...." Isn't this the literal truth? Commented Feb 16, 2016 at 0:00
  • 1
    It is. Perhaps I could change imagine to "know" or "understand". Commented Feb 17, 2016 at 13:21
  • Perhaps I have gotten myself confused (again). It seems where you say "target" you mean "source". The source_file (first) argument is where the link points, which is verbatim what you enter on the command. The target_file (second) argument becomes the name of the link unless what you enter is a directory, in which case the link name is the same as the basename of the source_file but placed in the directory target_file. Commented Apr 1, 2017 at 8:23
  • Y̶o̶u̶'̶r̶e̶ ̶r̶i̶g̶h̶t̶,̶ ̶t̶h̶e̶r̶e̶'̶s̶ ̶a̶ ̶m̶i̶s̶t̶a̶k̶e̶ ̶i̶n̶ ̶t̶h̶e̶ ̶a̶n̶s̶w̶e̶r̶.̶ ̶C̶r̶a̶z̶y̶ ̶h̶o̶w̶ ̶i̶t̶ ̶d̶i̶d̶n̶'̶t̶ ̶g̶e̶t̶ ̶c̶a̶u̶g̶h̶t̶ ̶s̶o̶o̶n̶e̶r̶.̶ ̶F̶i̶x̶i̶n̶g̶.̶ No, the answer was right. By the ln manpage, target is the first argument (where the link points to) whereas the second argument is simply referred to as the link (source is not mentioned). Commented Apr 1, 2017 at 10:35
  • 3
    In linux (gnu ln) the man page calls the first argument target and the second link (man7.org/linux/man-pages/man1/ln.1.html). But in BSD (including OS X) the first is called source and the second target (freebsd.org/cgi/man.cgi?ln). Quite confusing. Commented Jun 15, 2018 at 15:56
11

Using the -r (--relative) flag will make this work:

ln -sr foo ~/bin/foo_link 
1
  • 9
    Beware that -r is a GNUism, i.e. non POSIX so won't work in the OP case as the standard OS X ln command is BSD based. Commented Feb 16, 2016 at 0:11
5

To save some typing, you can do

ln -s "$PWD"/foo ~/bin/foo_link 
0
3

Use realpath

cd /Users/niels/something ln -s "$(realpath foo)" ~/bin/foo_link 
-1

How about:

 $ cd /Users/niels/something $ ln -s ./foo ~/bin/foo_link 
1
  • 1
    Nope, doesn't do the trick. Commented Apr 16, 2014 at 23:00

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.