I need a symlink that resolves relative to the directory it is placed in. What command is used to create such a thing?
5 Answers
- Go to the directory you want the link to reside in
- 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.
-
28No you don't. You just have to make sure that you specify the location relative to the link name instead of your current directory. May 28, 2010 at 8:26
-
7To 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.– MarianMay 30, 2010 at 14:27
-
2
-
2Instead of going down a directory and the up again, you can also just do
ln -s ./file linkname
since.
refers to the current directory.– pduMar 12, 2013 at 13:36 -
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
May 18, 2016 at 9:09
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.
-
5Thanks. The
-r
option is helpful when you are cross-compiling and need absolute paths on the build host but relative paths on the target. Sep 1, 2015 at 15:57 -
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 FossMar 13, 2019 at 15:47
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.– tripleeeApr 25, 2018 at 7:27 -
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.– tripleeeMar 7, 2019 at 15:14
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
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
-
It's a viable solution, so doesn't need to be a comment. This can stay as a separate answer.– slhckOct 5, 2011 at 20:43
-
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
– TimoMay 8, 2016 at 17:29 -
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. :)– TimoMay 8, 2016 at 17:33
-
@TimoLehto Perhaps you want to address the comment to the original author (Cody Hess). I only copyedited the post.– slhckMay 10, 2016 at 11:22
-
@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).– TimoMay 11, 2016 at 8:22