Reputation: 141
Suppose I have a path named:
/this/is/a/real/path
Now, I create a symbolic link for it:
/this/is/a/link -> /this/is/a/real/path
and then, I put a file into this path:
/this/is/a/real/path/file.txt
and cd it with symbolic path name:
cd /this/is/a/link
now, pwd command will return the link name:
> pwd
/this/is/a/link
and now, I want to get the absolute path of file.txt as:
/this/is/a/link/file.txt
but with python's os.abspath()
or os.realpath()
, they all return the real path (/this/is/a/real/path/file.txt
), which is not what I want.
I also tried subprocess.Popen('pwd')
and sh.pwd()
, but also get the real path instead of symlink path.
How can I get the symbolic absolute path with python?
Update
OK, I read the source code of pwd
so I get the answer.
It's quite simple: just get the PWD
environment variable.
This is my own abspath
to satify my requirement:
def abspath(p):
curr_path = os.environ['PWD']
return os.path.normpath(os.path.join(curr_path, p))
Upvotes: 11
Views: 11309
Reputation: 1030
from python 2.7.3 document:
os.path.abspath(path)¶
Return a normalized absolutized version of the pathname path. On most platforms, this is equivalent to normpath(join(os.getcwd(), path)).
the os.getcwd() will return a real path. e.g.
/home/user$ mkdir test
/home/user$ cd test
/home/user/test$ mkdir real
/home/user/test$ ln -s real link
/home/user/test$ cd link
/home/user/test/link$ python
>>> import os
>>> os.getcwd()
'/home/user/test/real'
>>> os.path.abspath("file")
'/home/user/test/real/file'
>>> os.path.abspath("../link/file")
'/home/user/test/link/file'
or
/home/user/test/link$ cd ..
/home/user/test$ python
>>> import os
>>> os.path.abspath("link/file")
'/home/user/test/link/file'
Upvotes: -1
Reputation: 8071
You can do this to traverse the directory:
for root, dirs, files in os.walk("/this/is/a/link"):
for file in files:
os.path.join(root, file)
This way you will get the path to each file, prefixed with the symlink name instead of the real one.
Upvotes: 0
Reputation: 3860
The difference between os.path.abspath
and os.path.realpath
is that os.path.abspath
does not resolve symbolic links, so it should be exactly what you are looking for. I do:
/home/user$ mkdir test
/home/user$ mkdir test/real
/home/user$ mkdir test/link
/home/user$ touch test/real/file
/home/user$ ln -s /home/user/test/real/file test/link/file
/home/user$ ls -lR test
test:
d... link
d... real
test/real:
-... file
test/link:
l... file -> /home/user/test/real/file
/home/user$ python
... python 3.3.2 ...
>>> import os
>>> print(os.path.realpath('test/link/file'))
/home/user/test/real/file
>>> print(os.path.abspath('test/link/file'))
/home/user/test/link/file
So there you go. How are you using os.path.abspath
that you say it resolves your symbolic link?
Upvotes: 16