2012-03-22 23 views
7

Tengo un script que busca un directorio que contiene un archivo específico, comenzando desde el directorio actual y subiendo por el árbol (intente averiguar dónde se encuentra el directorio .git)Compruebe si un directorio es un (sistema de archivos) raíz

Mi método es el siguiente:

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 

Ahora el problema con este método es que, si no se puede encontrar el directorio, se realiza un bucle (y eventualmente apilar-desbordamientos), porque al parecer unirse / y .. le da / nuevamente. Intenté comparar path con parent o sus repr s, pero eso no funcionó (siempre fueron distintos). Mi solución por ahora es incluir un contador de profundidad en el método recursivo y detenerme en algún umbral máximo aleatorio.

Mi pregunta es, por lo tanto, ¿existe una manera confiable de plataforma cruzada para comprobar si he llegado a una raíz en el sistema de archivos?

+1

No estoy seguro de si es confiable en todas las plataformas, pero si os.path.dirname (path) == path, entonces parece que la ruta es la raíz. –

Respuesta

7

No creo que pueda averiguar si es una raíz del sistema de archivos portátil, sin embargo, le sugiero que haga una llamada al os.path.realpath() tanto en el directorio actual como en el padre calculado y compare si son iguales - esto significa que estás haciendo girar tus ruedas y no tiene sentido seguir adelante.

Por ejemplo:

>>> os.path.realpath('/usr/bin/..') 
'/usr' 
>>> os.path.realpath('/usr/bin/../..') 
'/' 
>>> os.path.realpath('/usr/bin/../../..') 
'/' 
>>> os.path.realpath('/..') 
'/' 
16
if os.path.dirname(path) == path: 
    # you have yourself root. 
    # works on Windows and *nix paths. 
    # does NOT work on Windows shares (\\server\share) 
+1

Funciona en acciones de Windows, pero no indica que el recurso compartido sea la raíz ... piensa en \\ servidor como la raíz. Eso sinceramente tiene más sentido IMO de todos modos. –

+0

@nacitarsevaht Probablemente tengas razón. Pensar en \\ server como root tiene más sentido, pero hace un uso menos práctico, ya que enumerar los contenidos de \\ server a través de las herramientas normales que hacen "list dir" no es práctico. – ddotsenko

+0

Esta respuesta no funciona si la ruta contiene elementos "..", como en la respuesta de @ FatalError. – jmh

1

Esto funciona para nosotros en Linux. No estoy seguro acerca de Windows, sin embargo:

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) 

Utilizamos os.path.normpath (inicio) en la llamada a esta función.

Cuestiones relacionadas