Linux – re-create new link and remove the old link on one command

bashkshlinuxshell-scriptingsolaris

according to ln manual page:

   man ln


   -f, --force
          remove existing destination files

so as I understand if I want to re-create new link to some destination directory/file

I can simply do

    ln -s -f some_directory new_link

but this is not what I got from my linux/solaris machines

for example

  [u@h w]# mkdir dir1
  [u@h w]# ln -s dir1 link
  [u@h w]# ls -l


  drwxr-xr-x 2 root root 4096 Mar 16 20:26 dir1
  lrwxrwxrwx 1 root root    4 Mar 16 20:27 link -> dir1




   [u@h w]# ln -s -f dir1 new_link

now I accepted to see that new_link is now pointed to dir1 while "link" isn’t exists
but link still pointed to dir1 also?

how to recreate new link and on the same time remove the old link in one command ?

( I not want to use rm command )

  [u@h w]# ls -l
  drwxr-xr-x 2 root root 4096 Mar 16 20:26 dir1
  lrwxrwxrwx 1 root root    4 Mar 16 20:27 link -> dir1
  lrwxrwxrwx 1 root root    4 Mar 16 20:28 new_link -> dir1

Other different example

  # 
  # mkdir dir
  # 
  # ln -s dir link
  # 
  # mv dir dir_new
  # ls -l
  total 32
    drwxr-xr-x   2 root     root         117 Mar 16 21:44 dir_new
    lrwxrwxrwx   1 root     root           3 Mar 16 21:44 link -> dir
  # ln -s -f  dir_new link
  ln: cannot create link: File exists

is it possible to update the current link to point on new directory/file

( without to get File exists ? ) ,

or force to create the link again on different directory
?

Best Answer

The -f option allows you to overwrite the target file, i.e. the file with the name you're creating the link with, with a new link. It doesn't check for other links in the same directory.

Example:

$ touch file1
$ touch file2
$ ln -s file1 link1
$ ls -l
total 8
-rw-r--r--  1 jenny  staff    0 Mar 16 21:13 file1
-rw-r--r--  1 jenny  staff    0 Mar 16 21:13 file2
lrwxr-xr-x  1 jenny  staff    5 Mar 16 21:13 link1 -> file1
$ ln -s file2 link1
ln: link1: File exists
$ ln -s -f file2 link1
$ ls -l
total 8
-rw-r--r--  1 jenny  staff  0 Mar 16 21:13 file1
-rw-r--r--  1 jenny  staff  0 Mar 16 21:13 file2
lrwxr-xr-x  1 jenny  staff  5 Mar 16 21:14 link1 -> file2

If you just want to move the name of the link, so that instead of being called link1 it should be called newlink, just move it:

$ mv link1 newlink
$ ls -l
total 8
-rw-r--r--  1 jenny  staff  0 Mar 16 21:13 file1
-rw-r--r--  1 jenny  staff  0 Mar 16 21:13 file2
lrwxr-xr-x  1 jenny  staff  5 Mar 16 21:14 newlink -> file2

If you're working with directories instead of files, you need to add the option -n as well as -f:

$ ls -l
total 16
drwxrwxr-x 2 jenny jenny 4096 Mar 18 10:37 dir1
drwxrwxr-x 2 jenny jenny 4096 Mar 18 10:37 dir2
$ ln -s dir1 link1
$ ls -l
total 20
drwxrwxr-x 2 jenny jenny 4096 Mar 18 10:37 dir1
drwxrwxr-x 2 jenny jenny 4096 Mar 18 10:37 dir2
lrwxrwxrwx 1 jenny jenny    4 Mar 18 10:37 link1 -> dir1
$ ln -s -n -f dir2 link1
$ ls -l
total 20
drwxrwxr-x 2 jenny jenny 4096 Mar 18 10:37 dir1
drwxrwxr-x 2 jenny jenny 4096 Mar 18 10:37 dir2
lrwxrwxrwx 1 jenny jenny    4 Mar 18 10:38 link1 -> dir2