How do I create a relative symbolic link in Linux?

66

16

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

Jeremiah Rose

Posted 2010-05-28T08:21:07.590

Reputation: 1 569

Answers

79

  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.

Jeremiah Rose

Posted 2010-05-28T08:21:07.590

Reputation: 1 569

24No you don't. You just have to make sure that you specify the location relative to the link name instead of your current directory. – Ignacio Vazquez-Abrams – 2010-05-28T08:26:45.367

5To 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. – Marian – 2010-05-30T14:27:52.500

1ln -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 – Lorenz Meyer – 2016-05-18T09:09:45.613

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. – thenaglecode – 2016-09-23T04:41:03.140

2exactly equivalent: ln -s ../some/other/file /some/dir/linkname – sehe – 2011-12-22T12:07:09.457

1Instead of going down a directory and the up again, you can also just do ln -s ./file linkname since . refers to the current directory. – pduersteler – 2013-03-12T13:36:53.720

31

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.

Bluewind

Posted 2010-05-28T08:21:07.590

Reputation: 411

2Thanks. The -r option is helpful when you are cross-compiling and need absolute paths on the build host but relative paths on the target. – Robert Calhoun – 2015-09-01T15:57:22.610

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 – Ray Foss – 2019-03-13T15:47:14.707

2

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.

tripleee

Posted 2010-05-28T08:21:07.590

Reputation: 2 480

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 – 2018-04-25T07:27:33.797

That link is now dead. Try https://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.

– tripleee – 2019-03-07T15:14:17.780

0

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  

TryHarder

Posted 2010-05-28T08:21:07.590

Reputation: 172

0

Relative links were tricky for me on OS X, i.e.

~/Dropbox/git/dave-bot $ ln -s ../codyhess/bin ~/bin
~/Dropbox/git/dave-bot $ ln -s ../codyhess/bin/ ~/bin

both did not work (something was created but it wasn't a directory). I created the desired link by using absolute paths.

~/Dropbox/git/dave-bot $ ln -s ~/Dropbox/git/codyhess/bin/ ~/bin

Cody Hess

Posted 2010-05-28T08:21:07.590

Reputation: 147

1Your 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 – 2016-05-08T17:29:24.803

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. :) – Timo – 2016-05-08T17:33:05.197

@TimoLehto Perhaps you want to address the comment to the original author (Cody Hess). I only copyedited the post. – slhck – 2016-05-10T11:22:24.460

@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 – 2016-05-11T08:22:18.660

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. – Timo – 2016-05-11T08:29:42.727

@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. – slhck – 2016-05-11T09:00:17.343

@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 – 2018-04-25T07:18:57.480

It's a viable solution, so doesn't need to be a comment. This can stay as a separate answer. – slhck – 2011-10-05T20:43:52.383