11 votes

Vérifier si un répertoire est une racine (système de fichiers)

J'ai un script qui recherche un répertoire contenant un fichier spécifique, en partant du répertoire courant et en remontant l'arborescence (pensez à essayer de trouver l'endroit où se trouve le .git s'installe dans le répertoire).

Ma méthode ressemble à ceci :

def getDir(self,cwd):
  path = os.path.abspath(cwd)
  if not os.path.isdir(path):
    raise RuntimeError("getDir should not be run on files")
  if FILE in os.listdir(path):
    return path
  parent = os.path.join(path, os.path.pardir)
  if os.access(parent, os.R_OK) and os.access(parent, os.X_OK):
    return self.getDir(parent)
  else
    return None

Le problème avec cette méthode est que, si elle ne trouve pas le répertoire, elle tourne en boucle (et finit par déborder de la pile) parce que, apparemment, en rejoignant / y .. vous donne / encore. J'ai essayé de comparer path con parent ou leur repr mais cela n'a pas fonctionné (ils étaient toujours distincts). Ma solution pour l'instant est d'inclure un compteur de profondeur dans la méthode récursive et de s'arrêter à un seuil maximum aléatoire.

Ma question est donc la suivante : existe-t-il un moyen fiable et multiplateforme de vérifier si j'ai atteint une racine dans le système de fichiers ?

24voto

ddotsenko Points 2036
if os.path.dirname(path) == path:
    # you have yourself root.
    # works on Windows and *nix paths.
    # does NOT work on Windows shares (\\server\share)

10voto

FatalError Points 19772

Je ne pense pas que vous puissiez savoir s'il s'agit d'un système de fichiers Root de manière portative, cependant je suggérerais de faire un appel à os.path.realpath() sur le dir actuel et sur le parent calculé et comparez s'ils sont identiques - cela signifie que vous faites du sur-place et qu'il est inutile de continuer.

Par exemple :

>>> os.path.realpath('/usr/bin/..')
'/usr'
>>> os.path.realpath('/usr/bin/../..')
'/'
>>> os.path.realpath('/usr/bin/../../..')
'/'
>>> os.path.realpath('/..')
'/'

1voto

Cela fonctionne pour nous sous Linux. Je ne suis pas sûr pour Windows, cependant :

def _find_root(start, stop, func=os.path.exists):
    """Search up the start hierarchy for stop; return None at the FS root.

    Uses func() to determine if stop exists; default is os.path.exists().
    """
    if func(os.path.join(start, stop)):
        return start
    else:
        if os.path.samefile(start, os.path.dirname(start)):
           return None
        else:
           return _find_root(os.path.dirname(start), stop)

Nous utilisons os.path.normpath(start) dans l'appel à cette fonction.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X