Mailing List Archive

I'll pay $40 in e-gold if you'll fix this bug.
Greetings to Pythonistas, Pythoniandos and Python Hackers
everywhere!


I have written some Python scripts for my own amusement, and
I'm stymied by a "bug" involving traversing symlinked
directories in a Linux ext2 filesystem.


I'm offering 40.00 USD for a patch to my code that makes my
"scoot()" function do what I want it to, like this:


------- begin imaginary bash transcript
bash$ cd /tmp
bash$ mkdir dirOne
bash$ mkdir dirTwo
bash$ mkdir dirTwo/dirThree
bash$ ln -s dirTwo/dirThree .
bash$ cd dirThree
bash$ echo "hi there" > file.txt
bash$ scoot.py file.txt ../dirOne
bash$ cd /tmp
bash$ cd dirOne
bash$ ls -al
total 3
drwx------ 2 zooko zooko 1024 Jun 8 01:10 .
drwx------ 4 zooko zooko 1024 Jun 8 01:07 ..
-rw------- 1 zooko zooko 9 Jun 8 01:09 file.txt
bash$ cd /tmp/dirThree
bash$ ls -al
total 2
drwx------ 2 zooko zooko 1024 Jun 8 01:10 .
drwx------ 3 zooko zooko 1024 Jun 8 01:07 ..
lrwxrwxrwx 1 zooko zooko 21 Jun 8 01:10 file.txt -> ../../dirOne/file.txt
bash$ cat file.txt
hi there
bash$
------- end imaginary bash transcript


Currently, it does this:


------- begin actual bash transcript
bash$ cd /tmp
bash$ mkdir dirOne
bash$ mkdir dirTwo
bash$ mkdir dirTwo/dirThree
bash$ ln -s dirTwo/dirThree .
bash$ cd dirThree
bash$ echo "hi there" > file.txt
bash$ scoot.py file.txt ../dirOne
/bin/mv: cannot create regular file `../dirOne/file.txt': No such file or directory
bash$ cd /tmp
bash$ cd dirOne
bash$ ls -al
total 5
drwx------ 2 zooko zooko 1024 Jun 8 01:12 .
drwxrwxrwt 12 root root 4096 Jun 8 01:12 ..
bash$ cd /tmp/dirThree
bash$ ls -al
total 3
drwx------ 2 zooko zooko 1024 Jun 8 01:12 .
drwx------ 3 zooko zooko 1024 Jun 8 01:12 ..
-rw------- 1 zooko zooko 9 Jun 8 01:12 file.txt
bash$ cat file.txt
hi there
bash$
------- end actual bash transcript


The code for "scoot.py" and the related functions in "zutil.py"
is available at
"http://wildgoose.tandu.com/~zooko/PythonHacking/".



I have $40.00 worth of e-gold ("http://e-gold.com/") which
I'll give to the author of the best, most elegant, solution
(IMO, of course).


If you create an e-gold account (takes less than 5 minutes)
then I can transfer the money to you in instantaneous digital
form, or if you prefer I'll have e-gold.com debit my account
and cut you a snail mail check.


I'll keep the newsgroup posted of what kind of response I get
to this offer.


:-)


Regards,

Zooko

-------
"Must it be assumed that because we are engineers beauty is not
our concern, and that while we make our constructions robust
and durable we do not also strive to make them elegant?"
-- Gustave Eiffel
I'll pay $40 in e-gold if you'll fix this bug. [ In reply to ]
Hi,

Maybe you get confused a bit by the bash!!!

Try following:
bash$ tcsh
tcsh: cd /tmp/
tcsh: mkdir dirOne
tcsh: mkdir dirTwo
tcsh: mkdir dirTwo/dirThree
tcsh: ln -s dirTwo/dirThree/ .
tcsh: cd dirThree/
tcsh: pwd
/tmp/dirTwo/dirThree

Do the same with the bash (removing the directories of course):
bash$ cd /tmp/
bash$ mkdir dirOne
bash$ mkdir dirTwo
bash$ mkdir dirTwo/dirThree
bash$ ln -s dirTwo/dirThree/ .
bash$ cd dirThree/
bash$ pwd
/tmp/dirThree

The tcsh gives the right answer. You are in the /tmp/dirTwo/dirThree directory. If you try
to move a file with "mv file.txt ../dirOne/file.txt" you can´t do that because there is no
directory dirOne !!!

Python works like tcsh. If you try the following you get the right answer:
bash$ cd /tmp/dirThree/
bash$ python
Python 1.5.1 (#1, May 6 1998, 01:48:27) [GCC 2.7.2.3] on linux-i386
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> import os
>>> os.getcwd()
'/tmp/dirTwo/dirThree'

My suggestion:

You can test if there are symbolic links in your path (e.g. os.path.islink("/tmp/dirThree")
within Python) or you can prove that /tmp/dirThree is in reality /tmp/dirTwo/dirThree and
life with that fact ...

Cheers,

Jan
I'll pay $40 in e-gold if you'll fix this bug. [ In reply to ]
Hi,

Maybe you get confused a bit by the bash!!!

Try following:
bash$ tcsh
tcsh: cd /tmp/
tcsh: mkdir dirOne
tcsh: mkdir dirTwo
tcsh: mkdir dirTwo/dirThree
tcsh: ln -s dirTwo/dirThree/ .
tcsh: cd dirThree/
tcsh: pwd
/tmp/dirTwo/dirThree

Do the same with the bash (removing the directories of course):
bash$ cd /tmp/
bash$ mkdir dirOne
bash$ mkdir dirTwo
bash$ mkdir dirTwo/dirThree
bash$ ln -s dirTwo/dirThree/ .
bash$ cd dirThree/
bash$ pwd
/tmp/dirThree

The tcsh gives the right answer. You are in the /tmp/dirTwo/dirThree directory. If you try
to move a file with "mv file.txt ../dirOne/file.txt" you can´t do that because there is no
directory dirOne !!!

Python works like tcsh. If you try the following you get the right answer:
bash$ cd /tmp/dirThree/
bash$ python
Python 1.5.1 (#1, May 6 1998, 01:48:27) [GCC 2.7.2.3] on linux-i386
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> import os
>>> os.getcwd()
'/tmp/dirTwo/dirThree'

My suggestion:

You can test if there are symbolic links in your path (e.g. os.path.islink("/tmp/dirThree")
within Python) or you can prove that /tmp/dirThree is in reality /tmp/dirTwo/dirThree and
life with that fact ...

Cheers,

Jan
I'll pay $40 in e-gold if you'll fix this bug. [ In reply to ]
Jan Walter <jan@q-bus.de> wrote:
: Hi,

: Maybe you get confused a bit by the bash!!!

: Try following:
: bash$ tcsh
: tcsh: cd /tmp/
: tcsh: mkdir dirOne
: tcsh: mkdir dirTwo
: tcsh: mkdir dirTwo/dirThree
: tcsh: ln -s dirTwo/dirThree/ .
: tcsh: cd dirThree/
: tcsh: pwd
: /tmp/dirTwo/dirThree

: Do the same with the bash (removing the directories of course):
: bash$ cd /tmp/
: bash$ mkdir dirOne
: bash$ mkdir dirTwo
: bash$ mkdir dirTwo/dirThree
: bash$ ln -s dirTwo/dirThree/ .
: bash$ cd dirThree/
: bash$ pwd
: /tmp/dirThree

: The tcsh gives the right answer. You are in the /tmp/dirTwo/dirThree directory. If you try
: to move a file with "mv file.txt ../dirOne/file.txt" you can@t do that because there is no
: directory dirOne !!!

: Python works like tcsh. If you try the following you get the right answer:
: bash$ cd /tmp/dirThree/
: bash$ python
: Python 1.5.1 (#1, May 6 1998, 01:48:27) [GCC 2.7.2.3] on linux-i386
: Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
:>>> import os
:>>> os.getcwd()
: '/tmp/dirTwo/dirThree'

: My suggestion:

: You can test if there are symbolic links in your path (e.g. os.path.islink("/tmp/dirThree")
: within Python) or you can prove that /tmp/dirThree is in reality /tmp/dirTwo/dirThree and
: life with that fact ...

: Cheers,

: Jan

It is not a matter of "correctness", but of perceived current
pathname. In that same tcsh, if you echo $cwd, you will get the same
value that bash returns, there are some systems where using this
"faked" value is required (Automounter V1 systems for example). Both
csh and tcsh have common, documentated add-ons (alias pwd 'echo $cwd')
to give the same functionality as bash.

But, the getcwd(3) C function performs a call to traverse up the tree
to retrieve the pathname. This is because a process only holds the
inode of the current directory, not the path that got it there.

Using relative pathnames with symbolic links is problematic at times,
but they aren't "incorrect." Symbolic links have to be organized
properly; if they are not, you have odd side-effects. These are the
Facts of Life (I always like "Jo" myself).

-Arcege