Eric H.
Eric H.

Reputation: 2232

Python : getcwd and pwd if directory is a symbolic link give different results

If my working directory is a symbolic link, os.getcwd() and os.system("pwd") do not give the same result. I would like to use os.path.abspath(".") to get the full path of my working directory (or a file in it), on purpose, not to get the same result than os.path.realpath(".").

How to get, in python 2.7, something like os.path.abspath(".", followlink=False) ?

Example : /tmp is a symbolic link to /private/tmp

cd /tmp
touch toto.txt
python
print os.path.abspath("toto.txt")
--> "/private/tmp/toto.txt"
os.system("pwd")
--> "/tmp"
os.getcwd()
--> "/private/tmp"

How can I get "/tmp/toto.txt" from the relative path "toto.txt" ?

Upvotes: 4

Views: 2134

Answers (2)

qneill
qneill

Reputation: 1704

If you want to use os.system(), use os.system("/bin/pwd -L") to get the logical path for the current working directory.

If running from a bash shell just use "$PWD", or from python use os.environ["PWD"] without having to fork a process with os.system().

But both of these solutions assume you're in the directory where the file is.

Building on the interface from Eric H:

import os,subprocess
def abspath(pathname):
    '''Return logical path (not physical) for pathname using Popen'''
    if pathname[0]=="/":
        return pathname
    lpwd = subprocess.Popen(["/bin/pwd","-L"],stdout=subprocess.PIPE, shell=True).communicate()[0].strip()
    return(os.path.join(lpwd,pathname))

def abspathenv(pathname):
    '''Return logical path (not physical) for pathname using bash $PWD'''
    if pathname[0]=="/":
        return pathname
    return(os.path.join(os.environ["PWD"],pathname))

print(abspath("foo.txt"))
print(abspathenv("foo.txt"))

Upvotes: 3

Eric H.
Eric H.

Reputation: 2232

A solution is :

from subprocess import Popen, PIPE

def abspath(pathname):
    """ Returns absolute path not following symbolic links. """
    if pathname[0]=="/":
        return pathname
    # current working directory
    cwd = Popen("pwd", stdout=PIPE, shell=True).communicate()[0].strip()
    return os.path.join(cwd, pathname)

print os.path.abspath("toto.txt")  # --> "/private/tmp/toto.txt"
print abspath("toto.txt")          # --> "/tmp/toto.txt"

Upvotes: 1

Related Questions