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?
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?
79
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.
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.
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.
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.
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.7800
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
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
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
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
1
ln -s somedir/original-dir link-name
does not work. It creates a directory with namelink-name
that contains an invalid link. The command that works isln -sr somedir/original-dir link-name
– Lorenz Meyer – 2016-05-18T09:09:45.613To 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.1402exactly equivalent:
ln -s ../some/other/file /some/dir/linkname
– sehe – 2011-12-22T12:07:09.4571Instead 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