这是一个微妙的问题,我知道,但我希望你能忍受我一会儿。
假设/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.abspath
,os.path.realpath
,os.path.expanduser
或os.path.relpath
。
答案 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)