2016-05-02 110 views
4

我使用os.walkfollowlinks=True,但我打了一個地方,一個符號鏈接指向它自己的目錄,從而導致一個無限循環。在這種情況下,罪魁禍首是/usr/bin/X11其名單如下所列:避免無限遞歸與os.walk

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

有什麼辦法避免以下鏈接要麼...,我會假設,會導致類似的問題?我想我可以用os.readlink來檢查,然後與當前路徑進行比較。有沒有其他解決方案呢?

+1

鏈接如'a - > b'和'b - > a'怎麼辦? –

+0

是的,這可能會導致更大的問題。就像要保持搜索的目錄列表,其中變大又醜的快速 – Eric

+0

@Eric:爲什麼會是這樣醜嗎? –

回答

4

如果要避免遞歸,沒有辦法避免存儲所有訪問目錄的集合。您不需要使用readlink,但是,您可以只存儲inodes。這避免了路徑規範化的問題。

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) 
+0

好吧,這並不一定是醜陋=) – Eric

+0

如果你的符號連接跨越文件系統邊界這不是冒險?你可以在兩個不同的文件系統上擁有相同的inode文件,不是嗎? – gimboland

+1

@gimboland:看看代碼:'dirkey = st.st_dev,st.st_ino'。 –

2

爲了完全避免無限遞歸問題(鏈接指向永遠的地方),您需要存儲您已經訪問的文件和/或目錄。

來自pynotify模塊的人員具有相同的問題並使用了描述的方法。修補程序位於鏈接中;)