Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Absolute path of a path



On Mon, 20 Dec 2010 11:26:45 +0100
Vincent Lefevre <vincent@xxxxxxxxxx> wrote:
> On 2010-10-28 12:52:50 +0200, Vincent Lefevre wrote:
> > On 2010-10-28 12:44:51 +0200, Vincent Lefevre wrote:
> > > FYI:
> > > 
> > > ypig:~> realpath symlink/../vlefevre/symlink
> > > /home/vlefevre
> > > 
> > > ypig:~> echo symlink/../vlefevre/symlink(:A)
> > > /home/vlefevre/vlefevre/symlink
> > > 
> > > where symlink is a symbolic link to ".".
> > 
> > I think that this is even a bug in zsh, as
> > 
> > ypig:~> echo symlink/../vlefevre/symlink2(:A)
> > zsh: no match
> > 
> > So, it seems that resolution as been done correctly (it is
> > detected that symlink/../vlefevre/symlink exists but not
> > symlink/../vlefevre/symlink2), however the output for the
> > former one /home/vlefevre/vlefevre/symlink doesn't exist
> > (there's no vlefevre file or directory in /home/vlefevre).
> 
> I've reported the following bug on the Debian BTS about this:
> 
>   http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=607615

I'm not convinced this is a bug.  It may be strange, but as it's an
example manufactured to show strangeness, that's probably not
too surprising.

Let's leave (:A) out of this to begin with.  We only need one fact about
it: it's in a set of globbing flags, so that means it forces the
expression to be treated as a glob, with 'no match' (or equivalent)
behaviour:

% cd ~/tmp
% ln -s . symlink
% echo symlink/../tmp/symlink(N)
symlink/../tmp/symlink
% echo symlink/../tmp/symlink2(N)
# empty

This behaviour I've shown so far is correct: symlink/../tmp/symlink is
an entry in the file system (it's a symbolic link to nothing, but that's
not a 'no match' condition), whereas symlink/../tmp/symlink2 isn't.
Until *after* you applied :A, zsh just passes it as a string to the OS,
which blindly follows it: down into symlink (doesn't change the physical
directory), then up (does), then back down into tmp... oh look, there's
a symlink entry here, so it exists.

It's only at this stage that the flags in globbing are applied.  So zsh
follows the entirely different rules in this case:

  Note that resolution of â..â occurs before resolution of symbolic links

So we get (in my case, which is exactly parallel to yours)

  /home/pws/tmp/symlink/../tmp/symlink

becomes

  /home/pws/tmp/tmp/symlink

This is the key point.  This is a different rule from how the OS tracks
a file name during globbing.  We do not want to mess about with the
globbing rules just because the file name is going to be modified in
some way after use; in particular, we don't know in general that a
modifier is going to produce a real file name, consider :t.

Now we try and do the following:

  Resolve use of symbolic links where possible
                                ^^^^^^^^^^^^^^

Well, it's not possible.  /home/pws/tmp/tmp doesn't exist, so we're
stuck at that point.  Note also the rule inherited from :a

  Note that the transformation takes place even if the
  file or any intervening directories do not exist.

So it's not an error that we can't do anything more, it just stops
trying to do anything with it at that point and returns what it's got.

If you don't want it to check for an entry in the file system, i.e. you
don't want globbing rules on the file before the :A modifier is applied,
you need to use parameter substitution,
e.g. ${${:-symlink/../tmp/symlink}:A}, and this gives the same answer in
both cases (and in both cases the filename is useless).  But this is the
right thing to do if you know you're about to create a path which
initially (during globbing) might do something different from what
happens after you've applied the :A rules.

The moral is "don't expect globbing to follow rules applicable to
directory string transformation".

The problem underlying this is the vain attempt to make symbolic links
work logically with respect to ".." when the rule applied to entries in
the filesystem is different.  You can disguise a certain amount of the
illogic from the user, but you can't disguise it from the OS.

-- 
Peter Stephenson <pws@xxxxxxx>            Software Engineer
Tel: +44 (0)1223 692070                   Cambridge Silicon Radio Limited
Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, UK


Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom



Messages sorted by: Reverse Date, Date, Thread, Author