bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Using absolute path instead of relative path on all operations


From: Bob Proulx
Subject: Re: Using absolute path instead of relative path on all operations
Date: Sun, 8 Feb 2009 12:56:01 -0700
User-agent: Mutt/1.5.13 (2006-08-11)

Till Halbach wrote:
> I have come over something which I think of as a bug, but you might
> disagree.

Symlinks violate some principles of least surprise.  Therefore it is
no surprise that it is impossible to make all uses of symlinks
unsurprising.

> Consider
> $ cd
> $ mkdir dir1 dir2
> $ cd dir1
> $ ln -s ../dir2 link
> $ cd link

The shell now tries to create an imaginary world that preserves the
concept of logical paths.  It does this because most people want it do
so.  It tries to track this information using the shell $PWD variable.
It would show that you are in the ".../dir1/link".  But in reality at
this point you are actually in ".../dir2" by following the symlink.

> $ pwd
> gives $HOME/dir1/link

The shell is lying to you.  Try running 'pwd -P' (or /bin/pwd)
instead.  Then you will see the actual path.

> but
> $ ls ..
> lists $HOME instead of dir1. Or, if you (being in link/)
> $ cp file ..
> the file gets copied into $HOME, not dir1/, i.e., the absolute path is
> always used, ignoring any links.

Note that '.' and '..' are real directory entries.  They are not
pseudo entries.  The shell covers them with fake entires for the
purpose of 'cd' to change the behavior into logical paths when
symlinks are in use.  But that does not remove the underyling entries.
All operating system kernel system calls use the real entries.  The
fake entries are an imaginary world created within the process model
of new-style, symlink-aware command shells.

> I believe the path $PWD should always be used instead of the absolute
> one. Thus, in the example, 'file' should be copied from dir2/ (or link/)
> into dir1/.

Perl, for example, has no built-in knowledge of the shell's attempt to
create an imaginary world with logical paths.

  cd $HOME
  perl -le 'chdir("/tmp");print $ENV{PWD};'

Because of this any command executed as a child of that process cannot
trust that $PWD contains useful information.  They use the real
information provided by the operating system kernel filesystem
interface.  Perl was handy here but really I could use any program
that is not-the-command-shell as an example here.

The $PWD process environment variable is a construct created by the
command shell.  The chdir(2) operating system call does not modify any
process environment variable.  Keeping those two in sync is not an
operating system function and is never automatic.  It is only done as
a convention by some programs, notably the command shell but very few
others.  When mixing programs with different conventions one will
always be surprisingly different than expected from the other one.

Often people go through this process of discovery and then decide that
the imaginary world created by the shell and layered on top of the
physical filesystem is the source of trouble and turn off logical
paths in the shell.  (See the bash 'set -o physical' option.)  Then
after using the system that way for a while they miss the ability to
"back out" of directories they arrived at through a symlink by using
"cd ..".  They then restore the default shell behavior and live in the
imaginary world again.  They have learned that it is imaginary but
also now know the real boundaries of it and can work around the
inconsistencies.

Bob




reply via email to

[Prev in Thread] Current Thread [Next in Thread]