1

I have a symlink for my live server called current and I have releases in the releases directory, i.e current -> releases/2012-05-08_15-13

If I want to update the symlink of my current directory, I have to unlink/rm it and re ln -s it.

My question is: How can I remove the symlink and update it to the latest release in one step.

Sathyajith Bhat
  • 21,321
  • 22
  • 95
  • 134
mmrs151
  • 3,924
  • 2
  • 34
  • 38

5 Answers5

7

The form of ln is

ln -sf sourcefile targetlink

Try

ln -sf releases/2012-05-08_15-13 current

to remove the current and create the new link.

octopusgrabbus
  • 10,555
  • 15
  • 68
  • 131
hughw
  • 685
  • 1
  • 4
  • 12
  • 4
    try ln -sfn sourcefile targetlink or it won't work. At least on Linux. – hookenz Feb 06 '14 at 08:05
  • @Matt Why don't you post your comment as an answer and get credit for having the only answer with the right info? – ToddR Apr 06 '16 at 12:56
3

If you want to do it in a single command, do as @hughw suggests and run ln -sf.

If you want to replace the symlink atomically (ie. so that there's no point in time where the symlink doesn't exist) create a new symlink, then mv it over the old one.

Hasturkun
  • 35,395
  • 6
  • 71
  • 104
3

As suggested by ToddR, here is the only answer that actually works on maybe most flavours of Linux - definately Ubuntu - which uses ln from coreutils package). Let me prove it to you.

matthewh@xen:~$ mkdir -p releases/dirA
matthewh@xen:~$ mkdir -p releases/dirB
matthewh@xen:~$ ln -s releases/dirA
matthewh@xen:~$ ls -l dirA
lrwxrwxrwx 1 matthewh matthewh 13 Apr  7 09:58 dirA -> releases/dirA
matthewh@xen:~$ ln -sf releases/dirB
matthewh@xen:~$ rm dirA
matthewh@xen:~$ ln -s releases/dirA current
matthewh@xen:~$ ln -sf releases/dirB current
matthewh@xen:~$ ls -l current
lrwxrwxrwx 1 matthewh matthewh 13 Apr  7 09:59 current -> releases/dirA  <--- DOESN'T WORK!
matthewh@xen:~$ ln -sfn releases/dirB current <--- WORKS!
matthewh@xen:~$ ls -l current
lrwxrwxrwx 1 matthewh matthewh 13 Apr  7 09:59 current -> releases/dirB

So the correct method on Linux is:

ln -sfn source target

-n, --no-dereference treat LINK_NAME as a normal file if it is a symbolic link to a directory

This is essential, if you do not use -n switch you will end up with a symlink inside source directory named "target".

In my examples,

matthewh@xen:~$ ls -l releases/dirA/
total 0
lrwxrwxrwx 1 matthewh matthewh 13 Apr  7 10:03 dirB -> releases/dirB
hookenz
  • 36,432
  • 45
  • 177
  • 286
1

correct answer:

ln -s new current_tmp && mv -Tf current_tmp current

Move is atomic operation.

Don't use 'ln -snf'. strace 'ln -snf' shows two system calls unlink + symlink.

0

This example clears the use of -sfn switch:

drwxr-xr-x. 10 root    root         4096 Aug 25 18:24 .
dr-xr-xr-x. 25 root    root         4096 Aug 19 10:32 ..
lrwxrwxrwx.  1 wildfly wildfly        25 Aug 25 18:15 wildfly -> /opt/wildfly-8.2.0.Final/
drwxr-xr-x. 10 wildfly wildfly      4096 Aug 25 18:28 wildfly-8.2.0.Final

                                                link to            link
                                                  |                 |
[gecloud@ip-10-227-224-45 opt]$ sudo ln -sfn wildfly-8.2.0.Final /opt/wildfly
[gecloud@ip-10-227-224-45 opt]$ ls -la
total 115540
drwxr-xr-x. 10 root    root         4096 Aug 25 18:34 .
dr-xr-xr-x. 25 root    root         4096 Aug 19 10:32 ..
lrwxrwxrwx.  1 root    root           19 Aug 25 18:34 wildfly -> wildfly-8.2.0.Final
drwxr-xr-x. 10 wildfly wildfly      4096 Aug 25 18:28 wildfly-8.2.0.Final
Murphy
  • 536
  • 6
  • 13