Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I have two directories in my home: ~/dir1 and ~/dir2 with a file in the first: ~/dir1/file.txt Is there any way that I can make a symlink to it from ~/dir2 without moving to ~/ and if not why is that the case?

I've tried from ~/ running:

$ ln -s ./dir1/file.txt ./dir2/file.txt

but as I'd expect, that causes the resultant symlink to effectively point at ~/dir1/dir2/file.txt which makes sense but isn't what I actually want.

I've also tried:

$ ln -s ./dir1/file.txt ../dir2/file.txt

Which returns:

ln: failed to create symbolic link `../dir2/file.txt': No such file or directory

I'd expect this to just create a symlink ~/dir2/file.txt pointing to ~/../dir1/file.txt

So I suppose my real question is this: can I force ln to make a symlink to a file that it doesn't think exists?

Edit: For extra clarity as to what I'm trying to achieve, I want a single command that I can run from my home directory that will effectively do:

pushd dir2/ && ln -s ../dir1/file.txt && popd

or in Python (this is the closest I've come to what I want):

echo "import os; os.symlink('../dir1/file.txt', './dir2/file.txt')" | python
share|improve this question

2 Answers 2

up vote 1 down vote accepted

You can do either of

  1. Use absolute paths

    $ ln -s ~/dir1/file.txt ~/dir2
    $ readlink dir2/file.txt 
    /home/terdon/dir1/file.txt
    
  2. Use the right relative paths

    $ ln -s ../dir1/file.txt dir2/
    $ readlink dir2/file.txt 
    ../dir1/file.txt
    

Depending on your use case, one may be better than the other. Just remember that when creating links using relative paths, the paths must be relative to the target and not to your current location.

share|improve this answer
    
Thanks for your answer. Your first suggestion will work if I had absolute paths but I specifically interested in relative paths. Your second suggestion is synonymous with my second attempted command (missing the destination filename) but I got a file not found error (see above) on the first argument. Can I ask which linux distribution you are using? –  nettux443 May 13 at 23:37
    
@nettux443 huh, that's strange. I'm on LMDE (basically Debian testing) and bash 4.2.45. Note that my second suggestion is not the same as yours. You used ./dir and I'm using ../dir. The idea is that the path needs to be relative to the target. If you want to include the link's name, use ln -s ../dir1/file.txt ~/dir2/foo that will still work. It will also work irrespective of where you are. I just tried the above from /etc and it correctly created a file at ~/dir2/foo pointing to ~/dir1/file.txt. –  terdon May 13 at 23:41
    
@nettux443 no, ln only checks whether the file it creates exists. It's your job to make sure that the target is real. This will give no error for example: ln -s /fruble/bargle/bob /tmp/foo, it will happily and silently create a broken link. –  terdon May 13 at 23:43
    
Sorry you are right my second answer is not the same as your suggestion. Therein lies the problem. Your suggestion is what I meant to try.... hopefully won't make that mistake again! –  nettux443 May 13 at 23:46
    
@nettux443 lol, happens to the best of us :) –  terdon May 13 at 23:47

Your question is kinda confusing.

  1. You asked "Is there any way that I can make a symlink to it from ~/dir1 [...] ?" I suppose you meant "from ~/dir2", based on the rest of your post?

  2. Your first command

    $ ln -s ./dir1/file.txt ./dir2/file.txt

    does not do what you think it does. Assuming you're still in your home directory, the above command creates a symlink whose own path is ~/dir2/file.txt, and this symlink points literally to the path ./dir1/file.txt. Because said symlink resides in the directory ~/dir2, such target path resolves to ~/dir2/./dir1/file.txt, which further resolves to ~/dir2/dir1/file.txt (probably non-existent and not what you want). So I doubt why you said it resolves to ~/dir1/dir2/file.txt.

  3. Your 2nd command fails because there's no directory ../dir2 to put the symlink in, and that's what the error message meant.

  4. To answer your question, yes. The OS doesn't care whether your symlink points to a path with no valid filesystem object present.

Probably what you really want is something like

ln -s ../dir1/file.txt ./dir2/file.txt

I guess? This command creates a symlink whose own path is ./dir2/file.txt, and its target is the literal relative path ../dir1/file.txt. The final, absolute path pointed to by the symlink is ~/dir2/../dir1/file.txt, which resolves to ~/dir1/file.txt.

Note that the ~ symbol is a shell expandable character which expands to the absolute path of your home directory. ~-expansion is not part of OS path resolution.

Suggested reading

Linux manpages of path_resolution(7), symlink(7), ln(1) and ln(1p).

Edit

Clarifications & suggested reading.

share|improve this answer
    
I understand why my first command doesn't work, that I didn't expect to work but I thought I'd try it. The second command I feel would work if I could force it to make the link. Note your suggested command's arguments are the wrong way round. ln -s /path/to/file /path/to/new/link the command you've written is trying to make a link ~/dir1/file.txt pointing to ~/dir2/file.txt (backwards!!) :) –  nettux443 May 13 at 21:14
    
see my edited question for more detailed info on what I'm trying to achieve. –  nettux443 May 13 at 21:33

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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