91

I created this file structure:

test/src
test/firefox

When I run this command:

ln -s test/src test/firefox

I would expect a symbolic link test/firefox/src to be created pointing to test/src, however I get this error instead:

-bash: cd: src: Too many levels of symbolic links
  • What am I doing wrong?
  • Can you not create a symbolic link to one folder which is stored in a sibling of that folder?
  • What's the point of this?
  • I'm not sure I follow what you did. Please post the output of ls -ld test test/*, or the exact sequence of commands that you ran to create these files. – Gilles Jul 9 '14 at 0:53
  • mkdir test; mkdir test/src; mkdir test/firefox; ln -s test/src test/firefox – David Zorychta Jul 9 '14 at 1:14
  • With these commands, cd test/firefox/src would show the error cd: no such file or directory: test/firefox/src, because test/firefox/src is a dangling symbolic link. Are you running cd on some other symbolic link called src? – Gilles Jul 9 '14 at 1:18
  • I am sure you did something between the ln -s and the cd that you don't tell us. Assuming that there is only a test subdirectory in your current directory, a cd src (or whatever you executed) should throw an error. Did you put something into test/firefox? – Dubu Jul 9 '14 at 7:44
  • 5
    And as @Gilles gave a hint, that link will not do what you think it does. Symbolic links with relative targets are always relative to the symlink directory, not the directory from where you created the link. So, being in a directory /some/path, a ln -s test/src test/firefox will create a symlink pointing from /some/path/test/firefox/src to /some/path/test/firefox/test/src, not to /some/path/test/src. – Dubu Jul 9 '14 at 7:48
28

On the surface, what you've suggested you've tried works for me.

Example

$ mkdir -p test/src test/firefox

$ tree --noreport -fp
.
`-- [drwxrwxr-x]  ./test
    |-- [drwxrwxr-x]  ./test/firefox
    `-- [drwxrwxr-x]  ./test/src

Make the symbolic link:

$ ln -s test/src test/firefox

$ tree --noreport -fp
.
`-- [drwxrwxr-x]  ./test
    |-- [drwxrwxr-x]  ./test/firefox
    |   `-- [lrwxrwxrwx]  ./test/firefox/src -> test/src
    `-- [drwxrwxr-x]  ./test/src

Running it a 2nd time would typically produce this:

$ ln -s test/src test/firefox
ln: failed to create symbolic link ‘test/firefox/src’: File exists

So you likely have something else going on here. I would suspect that you have a circular reference where a link is pointing back onto itself.

You can use find to sleuth this out a bit:

$ cd /suspected/directory
$ find -L ./ -mindepth 15
  • 1
    find -L ./ -mindepth 15 revealed the culprit – user7610 Oct 13 '16 at 12:49
158

As Dubu points out in a comment, the issue lies in your relative paths. I had a similar problem symlinking my nginx configuration from /usr/local/etc/nginx to /etc/nginx. If you create your symlink like this:

cd /usr/local/etc
ln -s nginx/ /etc/nginx

You will in fact make the link /etc/nginx -> /etc/nginx, because the source path is relative to the link's path. The solution is as simple as using absolute paths:

ln -s /usr/local/etc/nginx /etc/nginx
  • 56
    This answer was clearer than the other one. "Use absolute paths." – wulftone Jun 17 '15 at 16:59
  • 1
    I can confirm that this worked for me on Windows using cygwin. Thanks! – dimiguel Sep 28 '15 at 16:59
  • I often have problems getting the arguments correct. On OSX and GNU Linux, they are reversed which confuses me even more. – Daniel W. Nov 21 '16 at 13:39
  • I still can't believe this works. – Gene Jan 17 '17 at 8:17
  • 4
    You can use relative links, but they should be based on the directory where the symbolic link is. In other words: the first argument should be the same that you would write after cd if you would like to go to the targeted directory from the directory where the symbolic link's file is. – totymedli Mar 14 '18 at 15:19
7

Symlinks are relative to the parent directory of the link, not of the current directory of the ln process.

When you do:

cd /top/dir
ln -s test/src test/firefox

(where test/firefox is a directory), you're making a test/firefox/src symlink whose target is test/src.

That test/src is relative to the test/firefox directory, so that's a symlink to /top/dir/test/firefox/test/src.

If you wanted that symlink to be a link to /top/dir/test/src, you'd need to write:

ln -s ../src test/firefox/

Or

ln -s /top/dir/test/src test/firefox/

though it's generally a bad idea to make symlinks to absolute paths as they are easily broken when directories are renamed or filesystems are mounted elsewhere.

With GNU ln, you can use its -r option to let it make the calculation by itself:

$ ln -rs test/src test/firefox/
$ ls -ld test/firefox/src
lrwxrwxrwx 1 chazelas chazelas 6 Nov 29 15:59 test/firefox/src -> ../src
3

Use the absolute path instead of the relative path, then it will work.

Eg:

ln -s /home/user/test/src /home/user/test/firefox
0

The answer is to use absolute path. But it can be annoying to type the full path for something that is in the current directory. You can use command substitution of pwd to avoid that. If your target is in the current directory:

ln -s "$(pwd)"/target abs/path/to/link 

If your link should be in the current directory:

ln -s /abs/path/to/target "$(pwd)"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.