ch.linghu
ch.linghu

Reputation: 141

How to get the symbolic path instead of real path?

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

Answers (3)

raptor.zh
raptor.zh

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

Paulo Almeida
Paulo Almeida

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

Dan Gittik
Dan Gittik

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

Related Questions