Subject: bug#6138: mv while maintaining relative symbolic links

From: Bob Proulx <[email-masked]>
Date: Fri, 7 May 2010 16:03:25 -0600

severity 6138 wishlist
thanks

Peng Yu wrote:
> I'm wondering if there is any tool that can do almost exact the same
> thing as mv, but it can maintain symbolic links.
> 
> mv doens't maintain relative symbolic links. For example, I have file
> /tmp/A/file1.txt and a symbolic link /tmp/file1.txt that point to
> A/file.txt (by the relative path). If I mv /tmp/A to /tmp/B, the link
> /tmp/file1.txt will be broken.

For clarification you said:

  file     /tmp/A/file1.txt
  symlink  /tmp/file1.txt -> A/file.txt

But I think you meant to say:

  file     /tmp/A/file1.txt
  symlink  /tmp/file1.txt -> A/file1.txt

 After moving /tmp/A to /tmp/B

  file     /tmp/B/file1.txt
  symlink  /tmp/file1.txt -> B/file1.txt (proposed)

This is not possible.  Symbolic links are simply files in the
filesystem.  Special files, of course, but otherwise just files.
The two files /tmp/file1.txt and /tmp/A/file1.txt are unrelated to
each other in any way other than by content of /tmp/file1.txt.

To do what you are asking would require that every move operation
consult the contents of every symlink on the filesystem and adjust
those other symlinks.  Worse this is not only on the current
filesystem but also on other filesystems.  Because symlinks are not
real file links but simply a run time name conversion a symlink may
exist on other filesystems.  Those other filesystems may be over NFS
or other network filesystem.  Other filesystems may not even be
powered up and online at the time!  Also other symlinks may point to
this file but only incidentally, in which case they would get changed
even though they are unrelated.

> Another example: I have file /tmp/file1.txt and symbolic link
> /tmp/A/file1.txt that points to ../file1.txt (by relative path). If I
> move /tmp/A to /tmp/B/A, the symbolic /tmp/A/file1.txt will be broken.

  file     /tmp/file1.txt
  symlink  /tmp/A/file1.txt -> ../file1.txt

 After moving to a different level of hiearchy:

  file     /tmp/file1.txt
  symlink  /tmp/A/B/file1.txt -> ../file1.txt

A tool is possible that reads the value of the link (readlink) and
then removes the old symlink and creates a new (unrelated) symlink in
the target location but with a new path calculated to the old
location.  That would not be a move operation.  That would be
something different that removed the old and created a new.

But if that is what you wanted then you probably wanted to convert the
symlink to an absolute path first and then you could move it.  Off the
top of my head here is a simple script that I haven't tested and may
or may not behave reasonably.  In particular error handling is poor.

  #!/bin/sh -e
  src=$1
  dst=$2
  path=$(readlink -f "$src")
  rm -f "$src"
  ln -s "$path" "$src"
  mv "$src" "$dst"

I am sure that there are related tools here but nothing immediately
comes to my mind.  I have always simply scripted the operation that I
required at the moment.

Bob