2016-05-02 26 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

@エリック:なぜそれは醜いでしょうか? –

答えて

4

再帰を避けたい場合は、訪問したすべてのディレクトリのセットを保存しないようにする方法はありません。 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) 
+0

よろしくお願いします。醜い=) – Eric

+0

シンボリックリンクがファイルシステムの境界を超えている場合、この危険はありませんか? 2つの異なるファイルシステム上で同じiノードを持つ異なるファイルを持つことはできますか? – gimboland

+1

@gimboland:コードを見てください: 'dirkey = st.st_dev、st.st_ino'。 –

2

リンクが無限に再帰することを完全に回避するには、すでに訪れたファイルやディレクトリを保存する必要があります。

pynotifyモジュールの人々は、同じ問題を抱え、説明された方法を使用しました。このパッチはリンクにあります)

関連する問題