使用 os.walk 避免无限递归

Avoiding infinite recursion with os.walk

我将 os.walkfollowlinks=True 一起使用,但我遇到了一个符号 link 引用它自己的目录的地方,导致无限循环。在这种情况下,罪魁祸首是 /usr/bin/X11 列表如下:

lrwxrwxrwx 1 root root           1 Apr 24  2015 X11 -> .

有什么方法可以避免跟随 link 到 ...,我认为这会导致类似的问题?我想我可以用 os.readlink 检查一下,然后与当前路径进行比较。还有其他解决方案吗?

为了完全避免无限递归的问题(links 指向任何地方)你需要存储文件 and/or 你已经访问过的目录。

来自 pynotify 模块的人遇到了同样的问题并使用了描述的方法。补丁在 link ;)

如果要避免递归,就无法避免存储一组所有访问过的目录。您不需要使用 readlink,但是,您可以只存储 inode。这完全避免了路径规范化的问题。

import os
dirs = set()
for dirpath, dirnames, filenames in os.walk('.', followlinks=True):
    st = os.stat(dirpath)
    scandirs = []
    for dirname in dirnames:
        st = os.stat(os.path.join(dirpath, dirname))
        dirkey = st.st_dev, st.st_ino
        if dirkey not in dirs:
            dirs.add(dirkey)
            scandirs.append(dirname)
    dirnames[:] = scandirs
    print(dirpath)