展开相对路径但不遵循Python中路径中的任何符号链接

时间:2013-06-22 15:43:46

标签: python system

这是一个微妙的问题,我知道,但我希望你能忍受我一会儿。

假设/tmp/dir/home/user/some/dir的符号链接。假设您当前的工作目录是/tmp/dir

即使像.这样的扩展似乎也不可能,因为os.getcwd()返回/home/user/some/dir而不是/tmp/dir,这是pwd命令返回的内容。相对目录也可以是../dir/../dir/subdir.././././dir/foo等。

所以我的问题:是否有任何可靠的函数可以执行相对路径的路径扩展,但不遵循相对路径中可能存在的符号链接。例如,如果是../dir/../dir/subdir,我希望获得/tmp/dir/subdir而不是/home/user/some/dir/subdir

为了避免得到我不想要的内容,答案不是os.path.abspathos.path.realpathos.path.expanduseros.path.relpath

2 个答案:

答案 0 :(得分:1)

好像you're not the first似乎注意到chdir(2)的奇怪行为。

Linux手册页中没有任何内容,但a similar page说...

  

int chdir(const char *path);

     

[...]

     

chdir()函数使 path 命名的目录成为新的   当前目录。如果 path 的最后一个组件是符号链接,    chdir()解析符号链接的内容。如果 chdir()函数失败,则当前目录不变。

......虽然没有解释为什么它解析了符号链接。

因此,即使你的shell另有说明,你在技术上也不能拥有/tmp/dir的当前工作目录。

但是,您可以利用shell的内置cd命令将环境变量PWD设置为您输入的值,这样您就可以执行此操作...

$ cd /tmp/dir
$ python
>>> import os
>>> os.getcwd()
'/home/user/some/dir'
>>> os.environ['PWD']
'/tmp/dir'
>>> os.path.normpath(os.path.join(os.environ['PWD'], '../dir/../dir/subdir'))
'/tmp/dir/subdir'

...虽然在没有从shell启动进程的情况下可能会失败。

答案 1 :(得分:0)

不确定这是您正在寻找的,但是......您可以编写一个函数,从相对路径和当前工作目录生成“逻辑”完整路径,然后检查生成的路径是否确实存在于系统上。该功能可能如下所示:

import os

def absolute_path(path):
    wd = os.getcwd()
    full = os.path.join(wd, path)

    parts = full.split(os.sep)
    kept = []
    skip = 0
    for part in reversed(parts):
        if part == '..':
            skip += 1
        elif skip == 0:
            kept.insert(0, part)
        else:
            skip -= 1
    return os.sep + os.path.join(*kept)