233

I am trying to use symbolic links. I did some reading and found the following commands:

Creation -> ln -s {/path/to/file-name} {link-name}
Update -> ln -sfn {/path/to/file-name} {link-name}
Deletion -> rm {link-name}

Creations and deletions work fine. But updates do not work. After performing this command, the symlink becomes invalid.

I have read here and there that it is not possible to update/override a symlink. So there is contradictory information on the net. Who is right? If a symlink can be updated/overridden, how can I achieve this?

Update

Here is my directory structure:

~/scripts/test/
~/scripts/test/remote_loc/
~/scripts/test/remote_loc/site1/
~/scripts/test/remote_loc/site1/stuff1.txt
~/scripts/test/remote_loc/site2/
~/scripts/test/remote_loc/site2/stuff2.txt
~/scripts/test/remote_loc/site2/
~/scripts/test/remote_loc/site3/stuff3.txt

From ~/scripts/test/, when I perform:

ln -s /remote_loc/site1 test_link

a test_link is created, and I can ls -l it, but it seems broken (contrary to what I said above in my question).

How can I perform a multiple directory level link?

4
  • 1
    I recommend to use unlink instead of rm. With unlink you never risk to lose any files in a source directory by accidentally using wrong switches.
    – Jpsy
    Jul 16, 2014 at 9:04
  • You are using a leading / in your command
    – Jamie Cook
    Aug 10, 2016 at 23:20
  • @jpsy your advice about unlink would be very good, if it was true. Try touch zzzz; unlink zzzz. (unlink calls, unlink same as rm, but with no fancy options, and no recursion). Oct 16, 2016 at 14:24
  • 1
    Why use of -n? (may be the problem). Also if your ln supports -t then use it, for these cases, and -T or destination/ for other cases. Oct 16, 2016 at 14:26

4 Answers 4

179

Using -f with ln will overwrite any link that was already there, so as long as you have the correct permissions, it should work... It's always worked for me. What operating system are you using?

10
  • I have updated my question with more information on my issue. May 17, 2012 at 12:56
  • 2
    If you switch the ln parameters, as I am prone to do, will the -f switch destroy your existing files (link targets)? In either case, we have the -i parameter (which will prompt the user for overwrite) as well, if you want a bit of security.
    – palswim
    Jan 3, 2015 at 6:10
  • 2
    @palswim This SO post implies it is safe because -f just calls unlink() and link() under the hood: stackoverflow.com/a/1466570/157385. I do wish I'd just remember the correct order, though! Feb 9, 2015 at 18:33
  • 10
    Does not work. Needs -n. See accepted answer. May 13, 2016 at 15:49
  • 4
    MacOS requires -n to update.
    – gone
    Feb 14, 2019 at 17:50
153

Ok, I found where my error is: one should not put the first / in path.

In other words, the commands in my questions should be:

Creation -> ln -s {path/to/file-name} {link-name}
Update -> ln -sfn {path/to/file-name} {link-name}

instead of

Creation -> ln -s {/path/to/file-name} {link-name}
Update -> ln -sfn {/path/to/file-name} {link-name}

considering my case.

7
  • 22
    For some additional information on why that is, the differences are one is a relative path (without the leading /) and the other is an absolute path (with the leading /). If you're administrating a Linux system it is CRITICAL that you understand the differences. For instance the difference between rm -rf ./* and rm -rf /.* decides whether you keep your job or not :)
    – Safado
    May 17, 2012 at 14:10
  • 6
    This doesnt answer the question 'how to update/overide a sym link'
    – Sirch
    May 17, 2012 at 15:53
  • The ln -sfn {path/to/file-name} {link-name} line does. May 17, 2012 at 17:27
  • 7
    -n (--no-dereference) makes it treat {link name} like a normal file rather than following the link. Given that you need to operate on that link not follow it you must use this option.
    – feldoh
    Nov 25, 2016 at 10:34
  • 2
    This answer should be highlight answer with -n parameter for replacing symbol link.
    – Nick Tsai
    Nov 25, 2017 at 5:30
15

First issue:

Quoting you:

Creations and deletions work fine. But updates do not work. After performing this command, the symlink becomes invalid.

The problem With the given directory structure:

~/scripts/test/ ~/scripts/test/remote_loc/ ~/scripts/test/remote_loc/site1/ ~/scripts/test/remote_loc/site1/stuff1.txt ~/scripts/test/remote_loc/site2/ ~/scripts/test/remote_loc/site2/stuff2.txt ~/scripts/test/remote_loc/site2/ ~/scripts/test/remote_loc/site3/stuff3.txt

and using the command:

ln -s /remote_loc/site1 test_link

Is that it creates a symbolic link in your $PWD, or present working directory, that points to a non-existing file off the /, or root, at /remote_loc/site1

If your PWD is in ~/scripts/ then you should have used this:

ln -s remote_loc/site1 test_link

else you could have used the full absolute path like:

ln -s /home/yourusername/remote_loc/site1 test_link

Second issue:

Quoting you:

I have read here and there that it is not possible to update/override a symlink. So there is contradictory information on the net. Who is right? If a symlink can be updated/overridden, how can I achieve this?

To answering your question "Who is right", I am not sure what exactly you read, or how it was understood. But, the following should help clear up:

  1. What can be updated, and
  2. What can not be updated without using appropriate switches.


Updating symbolic links with targets that are not directories.

ln -sf:
The -f or --force remove existing destination files, This is used to update a link's target or destination.

Example:

 ln -sf /tmp/test /tmp/test.link; ls -go /tmp |grep test
 -rw-r--r-- 1    0 Jun  8 17:19 test
 lrwxrwxrwx 1    9 Jun  8 17:27 test.link -> /tmp/test

But, as you can see, it will give the absolute path if absolute paths are in ln's arguments. Giving a full path is necessary when the present working directory is different than the link's parent directory.


Relative Paths:

ln -sfr:
The -r or --relative creates symbolic links relative to the link's location.

Example:

ln -sfr /tmp/test  /tmp/test.link  ; ls -go /tmp| grep test
-rw-r--r-- 1    0 Jun  8 17:19 test
lrwxrwxrwx 1    4 Jun  8 17:27 test.link -> test

But, updating a link to a directory will not work if the target is a directory.

Example:

ln -sf /tmp/testdir  /tmp/testdir.link  ; ls -go /tmp  |grep testdir
drwxr-xr-x 2 4096 Jun  8 17:48 testdir
lrwxrwxrwx 1    7 Jun  8 17:47 testdir.link -> testdir

As you can see, despite using absolute path names given in ln's argument above without the -r option, the symbolic link is still relative to the link.


Update Links to Directories:

ln -sfrn:
The -n or --no-dereference treats LINK_NAME as a normal file if it is a symbolic link to a directory.

Example:

ln -sfn /tmp/testdir /tmp/testdir.link; ls -go /tmp| grep testdir
drwxr-xr-x 2 4096 Jun  8 17:48 testdir
lrwxrwxrwx 1   12 Jun  8 17:48 testdir.link -> /tmp/testdir

As contrasted with:

ln -sfnr /tmp/testdir /tmp/testdir.link; ls -go /tmp| grep testdir
drwxr-xr-x 2 4096 Jun  8 17:48 testdir
lrwxrwxrwx 1    7 Jun  8 17:48 testdir.link -> testdir
8
$ touch test1 test2
$ ln -sf test2 test1
$ ls -l test[12]
lrwxrwxrwx 1 user01 user01 5 2012-05-17 14:41 test1 -> test2
-rw-r--r-- 1 user01 user01 0 2012-05-17 14:41 test2
1
  • When I perform tests with 1 level of directory, it works, but I am trying to use multi-level directories, and it does not work. I have updated my question. May 17, 2012 at 12:57

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .