如何在Python中获取符号链接目标?

57

使用Python,我需要检查数百个符号链接是否正确并在需要时重新创建它们。我现在所做的是比较我想要的和我拥有的真实路径,但这很慢,因为它通过NFS进行自动挂载。

否则,我将运行一个带有命令'ls -l'的子进程,并处理返回的字符串列表。我更喜欢使用Python库的更好的解决方案...

编辑1:我有:link_name -> link_target,然后link_target -> a_real_file。我需要从link_name中提取link_target,而不是a_real_file。如果真实文件不存在,我不关心。

编辑2:也许我表达不够清晰。我所说的正确符号链接是“指向预定义路径的链接,即使它不存在”。所以我需要检查:

link_name_1 -> target_1
link_name_2 -> target_2

这就是为什么我需要提取目标而不是实际路径。然后将其与参考文献(字典)进行比较。所以我的问题是:如何提取目标路径?

5个回答

76

os.readlink()的问题在于它只能解析链接的一级。我们可能会遇到这样的情况: A 链接到另一个链接 B,而 B 的链接是无效的。

$ ln -s /tmp/example/notexist /tmp/example/B
$ ln -s /tmp/example/B /tmp/example/A
$ ls -l /tmp/example
A -> /tmp/example/B
B -> /tmp/example/notexist

现在在 Python 中,os.readlink 会给你第一个目标。

>>> import os
>>> os.readlink('A')
'/tmp/example/B'

但在大多数情况下,我认为我们感兴趣的是已解析的路径。因此,pathlib 可以帮助解决这个问题:

>>> from pathlib import Path
>>> Path('A').resolve()
PosixPath('/tmp/example/notexist')

对于旧版本的Python:

>>> os.path.realpath('A')
'/tmp/example/notexist'

22

6
请考虑编辑您的帖子,增加关于您的代码是如何解决问题以及为什么会有帮助的更多解释。如果答案主要只包含代码(即使它能工作),通常不会帮助提问者理解他们的问题。 - SuperBiasedMan
1
谢谢Armin,这正是我所需要的。我已经能够获得目标,任务现在快多了。 - zorggy
原帖的问题在于他们不知道 os.readlink() 的存在。这个答案完全解决了这个问题。 - gerardw

16
在Python 3.9及以上版本中,可以使用pathlib.Path.readlink()
>>> p = Path('mylink')
>>> p.symlink_to('setup.py')
>>> p.readlink()
PosixPath('setup.py')

4
我认为每个人都应该尽可能停止使用 os.path,并转向使用 pathlib。很好地更新了旧问题并加入新功能,希望这能得到更高的评价。 - Tomerikoo

3
要确定链接是否失效,您可以使用os.walk并测试os.path.exists(path),如果链接失效则会返回False。然后,您可以使用os.path.realpath(path)来查找链接应该指向哪里。
大致如下(未经测试):
for root, dirs, files in os.walk('<path>'):
    for file in files:
         f = os.path.join(root, file)
         if os.path.islink(f) and not os.path.exists(f):
             print("Broken: {} -> {}".format(f, os.path.realpath(f)))

请注意,os.path.realpath() 目前在 Windows 上无法正常工作(http://bugs.python.org/issue9949)。 - antred
由于某些原因,我无法编辑此帖子。因此,我将我的编辑写成评论:第3行中的方法os.join不存在,应该是os.path.join - Nathanael Skrepek

-3

要确定一个目录条目是否是符号链接,请使用以下方法:

os.path.islink(path)

如果路径引用的是符号链接目录条目,则返回True。如果不支持符号链接,则始终为False。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接