How do I create a relative symbolic link in Linux?

78,608

Solution 1

  1. Go to the directory you want the link to reside in
  2. Run the command ln -s ../some/other/file linkname

The path you provide is stored with the file. When you access the file the stored path is looked up and expanded relative to the file. It does not know what directory you were in when you created the link.

Solution 2

Recent versions of GNU coreutils' ln (>= 8.16) support the --relative (or -r) option which means you can call ln -s with 2 absolute or relative (in respect to your working directory) paths and it will figure out the correct relative path that has to be written to the symlink.

Solution 3

What you need to understand is basically that a symlink is more like a text file than like a directory entry which contains a file. So if you

echo ../poo >/file/name

then that is quite similar to

ln -s ../poo /file/name

The system doesn't care if /file/../poo exists at all, it's just a piece of text which gets put into the symlink. When something tries to open the symlink, that's when the system tries to resolve it.

If you are using a shell with file name completion, this feature can confuse things by allowing you to complete a file name relative to your current working directory, even if you then end up using that as the target of a symlink in completely another directory.

Solution 4

I just wanted to further explain how to create a symlink using relative paths (with a detailed example).

As Ignacio Vazquez-Abrams mentioned in the comments, you must specify the file/folder location relative to where the symlink will be created, not relative to your current directory.

EXAMPLE

You are in /usr/share/nginx/html/_src/learn You will create a symlink coding in /usr/share/nginx/html

Create relative symlink(theory):

sudo ln -s /path/to/source/file-or-folder/relative/from/symlink /path/to/symlink/relative/to/current/location

Create actual relative symlink:

sudo ln -s ./_src/learn/coding ../../coding

More information (same example)

current path:                                  /usr/share/nginx/html/_src/learn
symlink(to be) relative to current path:       ../../coding                 
symlink location (absolute):                   /usr/share/nginx/html/coding
folder/file relative to symlink location:      ./_src/learn/coding
folder/file absolute path:                     /usr/share/nginx/html/_src/learn/coding  
Share:
78,608

Related videos on Youtube

javac
Author by

javac

Updated on September 17, 2022

Comments

  • javac
    javac almost 2 years

    I need a symlink that resolves relative to the directory it is placed in. What command is used to create such a thing?

  • Ignacio Vazquez-Abrams
    Ignacio Vazquez-Abrams about 14 years
    No you don't. You just have to make sure that you specify the location relative to the link name instead of your current directory.
  • Marian
    Marian about 14 years
    To help in understanding: The path you provide is stored with the file. When you access the file the stored path is looked up and expanded relative to the file. It does not know what directory you were in when you created the link.
  • slhck
    slhck over 12 years
    It's a viable solution, so doesn't need to be a comment. This can stay as a separate answer.
  • sehe
    sehe over 12 years
    exactly equivalent: ln -s ../some/other/file /some/dir/linkname
  • pdu
    pdu over 11 years
    Instead of going down a directory and the up again, you can also just do ln -s ./file linkname since . refers to the current directory.
  • Nick
    Nick almost 9 years
    Thanks. The -r option is helpful when you are cross-compiling and need absolute paths on the build host but relative paths on the target.
  • Timo
    Timo about 8 years
    Your initial try with relative links is just plain wrong and that's why it's not working. You've misunderstood how relative links work. There's nothing particularly tricky about it (not even if you are using OS X). Perhaps you got misguided by the other answers talking about chancing your working directory when you create the link. That was just to make it easier to do the link correctly and is in no way necessary. You do not define the relative path relative to your current dir, but to the directory of the link. This is what you were after: ln -s Dropbox/git/codyhess/bin ~/bin
  • Timo
    Timo about 8 years
    Also @slhck when someone is asking specifically how to create relative links in what world does a saying that you can do absolute links constitutes a "viable solution"? It specifically does not answer the OPs question and hence is quite the opposite of solution, it's no solution. This shouldn't be a comment nor an answer, it should be a question "How exactly do relative links work (explained so that mac users understand it)?". I hope this mac user now explained it well enough. :)
  • slhck
    slhck about 8 years
    @TimoLehto Perhaps you want to address the comment to the original author (Cody Hess). I only copyedited the post.
  • Timo
    Timo about 8 years
    @slhck, I directed it to you, because you deemed the solution as "viable" and your comment made me think that you would be the person to convince if one wanted to flag the answer as a "not an answer" (and get the flagging accepted).
  • Timo
    Timo about 8 years
    But also @cody-hess you too are welcome to recheck your answer in the light of my comments and perhaps you could remove it or otherwise revise it to be more useful. As of currently, it's just out of topic and misleading. Then again this would likely mean a full rewrite of the answer from a different angle.
  • slhck
    slhck about 8 years
    @TimoLehto Ah, with that comment I probably did not imply that it was a valid answer based on technical merits. Or I didn't see it at the time. It's an answer—the fact that it's a wrong answer does not make it applicable for flagging it as "not an answer". This flag should only be used for posts raising other questions or things that should have been comments. There's no convincing to be done. Just downvote the post and explain why.
  • Lorenz Meyer
    Lorenz Meyer about 8 years
    ln -s somedir/original-dir link-name does not work. It creates a directory with name link-name that contains an invalid link. The command that works is ln -sr somedir/original-dir link-name
  • thenaglecode
    thenaglecode almost 8 years
    To expand on @IgnacioVazquez-Abrams, The reason this is necessary is because the source argument to ln -s SOURCE DEST is the "string" that is placed in the link. not the actual path. if i copied this link file to my root directory, It would think the contents are located in '/../some/other/file' which obviously doesn't exist as root has no parent.
  • tripleee
    tripleee about 6 years
    @Timo It's also possible that the OP wants ln -s ../Dropbox/git/codyhess ~/bin which will create a symlink ~/bin/codyhess which points to ../Dropbox/git/codyhess relative to the ~/bin directory (as you say, regardless of where in the directory tree you are when you run this command). This is what happens if ~/bin already exists, and is a directory; your interpretation is that ~/bin does not exist yet, and the OP wants it to be a symlink to the other directory.
  • tripleee
    tripleee about 6 years
    This is abused by some system calls -- I know e.g. BSD used to allow you to symlink a particular system file to < to change how the system allocated memory. Of course there is no file named < in that directory, it's just a cheap way of creating a very small file-like thing which has some attractive properties over a regular text file on that particular platform.
  • tripleee
    tripleee over 5 years
    That link is now dead. Try man.openbsd.org/OpenBSD-5.3/man5/malloc.conf.5 but notice also that the behavior in more recent versions of OpenBSD is a lot less ... colorful.
  • Ray Foss
    Ray Foss over 5 years
    rdfind can produce some really bad symlinks that are not only absolute, but backtrack off of directories for no reason. ln -r -s targetfile myalias can help you fix it
  • The Fool
    The Fool over 2 years
    @pdu, this is what I did, but it didn't work. I had to go inside the folder and target upwards for it to be a valid symlink. That's actually why I ended up here on this question.