severity 585008 normal
tags 585008 + unreproducible wontfix
thanks

Nic Sandfield wrote:
> To reproduce:
> 
> mkdir a b
> ln -s a x
> ln -s -f b x

Thank you for your very nice small test case.  However I cannot
reproduce it.  Lenny ln 6.10 behaves the same as Squeeze/Sid ln 8.5
for this behavior.

> This worked in releases up to and including 'lenny'.

On both Lenny Stable 6.10 and Squeeze/Sid 8.5:

  $ mkdir a b
  $ ln -s a x
  $ ln -s -f b x
  $ ls -log x
  lrwxrwxrwx 1 1 2010-06-08 09:49 x -> a

That is expected behavior for GNU ln.  It differs from System V ln but
follows BSD ln behavior.  Because x resolves to a directory it is
exactly the same as if you had said:

  $ ln -s -f b a/b

Because x resolves to the directory a then the second invocation of ln
creates the target within the directory.  The -f removes a/b first but
that doesn't exist and so has no effect.  If it had not resolved to a
directory then the target would have been a file and the -f would have
forced removal of it.

  $ ls -log x/
  total 0
  lrwxrwxrwx 1 1 2010-06-08 09:49 b -> b

This is different than if x had not resolved to a directory.  If it
had not then and only then would x have been removed and replaced with
a symlink to b.

  $ rmdir a
  $ ln -s -f a x
  $ ln -s -f b x
  $ ls -log x
  lrwxrwxrwx 1 1 2010-06-08 10:05 x -> b

> The last line should have removed the previous link to 'a' and
> replaced it with the new link to 'b'.  However, 'ls -l' shows that
> the link 'x' still points to 'a'.  The failure to remove the former
> link is silent.

This has appeared as a portability problem a number of times in the
days past of BSD versus SysV behavior.  If there is any possibility of
having a symlink to a directory then the only portable solution is to
remove symlinks before creating them.  This is the only solution for
legacy systems such as HP-UX.  It works compatibly on GNU systems.
GNU follows the BSD style functionality.  You are probably wanting
SysV style functionality.  The only portable way to do this is to
remove the symlink first.

  rm -f x
  ln -s something x

Or you will want to use the BSD -n option.

  ln -sfn something x

I don't like the way things have evolved to this point over the
years.  But unfortunately it has gone on for so very many years that
it isn't behavior that can be changed easily.  I personally don't like
it but making large changes on behavior that has been static for
decades isn't desirable either.

BSD created this behavior and so must been seen as the reference
platform for it.  When BSD created this behavior I think they confused
an important point.  They wanted to make symlinks completely
transparent.  Commands wouldn't know about them.  If a symlink
resolves to directory then the command would just act completely as if
the target had always been a directory.  But the ln command creates
symlinks.  The point where things created problem behavior is that
symlinks in BSD are transparent to the ln command when creating them.
That is too bad.  SysV "fixed" this behavior.  In System V the ln
command removes the target symlink first as if it were a simple file
and not as if it resolves to a directory.  But that fixed behavior
hasn't propagated back to BSD.  And since GNU follows BSD in this
behavior it hasn't propagated there either.

This isn't a new topic.  It appears with some frequency and is
discussed on the upstream mailing list.  Here is some past discussion
of the topic.

  http://lists.gnu.org/archive/html/bug-fileutils/2003-10/msg00001.html
  http://lists.gnu.org/archive/html/bug-coreutils/2005-05/msg00171.html
  http://lists.gnu.org/archive/html/bug-coreutils/2005-08/msg00071.html
  http://lists.gnu.org/archive/html/bug-coreutils/2005-05/msg00177.html

I hope this helps to explain what is happening.

Bob



-- 
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]

Reply via email to