2010-07-25 8 views
7

Auf der Oberfläche ist das ziemlich einfach, und ich könnte es leicht selbst implementieren. Rufen Sie einfach nacheinander dirname() auf, um jede Ebene im Pfad der Datei nach oben zu gehen, und überprüfen Sie jeden einzelnen, um zu sehen, ob es das Verzeichnis ist, nach dem wir suchen.Wie kann ich feststellen, ob eine Datei ein Nachkomme eines bestimmten Verzeichnisses ist?

Aber Symlinks werfen das Ganze ins Chaos. Jedes Verzeichnis auf dem Pfad der Datei oder des Verzeichnisses, das geprüft wird, könnte ein Symlink sein, und jeder Symlink könnte eine willkürliche Kette von Symlinks zu anderen Symlinks haben. An diesem Punkt schmilzt mein Gehirn und ich bin mir nicht sicher, was ich tun soll. Ich habe versucht, den Code zu schreiben, um diese speziellen Fälle zu behandeln, aber es wird bald zu kompliziert und ich nehme an, dass ich es falsch mache. Gibt es eine einigermaßen elegante Möglichkeit, dies zu tun?

Ich benutze Python, also wäre jede Erwähnung einer Bibliothek, die das tut, cool. Ansonsten ist dies ein ziemlich sprachneutrales Problem.

Antwort

8

Verwenden os.path.realpath und os.path.commonprefix:

os.path.commonprefix(['/the/dir/', os.path.realpath(filename)]) == "/the/dir/" 

os.path.realpath werden alle Symlinks erweitern sowie .. im Dateinamen. os.path.commonprefix ist ein bisschen unbeständig - es prüft nicht wirklich auf Pfade, nur einfache String-Präfixe, also sollten Sie sicherstellen, dass Ihr Verzeichnis in einem Verzeichnis-Trennzeichen endet. Wenn Sie nicht tun, wird es dadurch /the/dirtwo/filename ist auch in /the/dir

+0

Vielleicht sind die Rand Fälle alle in meinem Kopf. Ich könnte schwören, dass Symlinks diesen Ansatz in einigen Fällen zum Scheitern bringen, aber ich kann keine Beispiele finden, um das zu beweisen. Ich habe das Gefühl, dass ich gegen einen Geist ankämpfe ... – mackstann

+1

Da jedes hierarchische Dateisystem, das mir einfällt, ein einziges, einzigartiges, kanonisches, richtig benanntes Verzeichnis benötigt, funktioniert das tatsächlich. Obwohl es kontraintuitiv sein kann, dass man von hier nach dort gelangen kann, muss für Verzeichnisse das "eine echte Elternteil" wahr sein oder es müssen schlimme Dinge passieren. – msw

+0

Nun, es ist eine gute Nachricht, das zu hören. Jetzt muss ich nur vier Fälle überprüfen (realpath und non-realpath für dir und Datei). Vielen Dank! – mackstann

1

Python 3.5 hat die nützliche Funktion os.path.commonpath:

Rückkehr der längste gemeinsame Teilpfad eines jeden Pfad in der Ablaufpfade. Raise ValueError, wenn Pfade sowohl absolute als auch relative Pfadnamen enthalten oder wenn Pfade leer sind. Im Gegensatz zu commonprefix() gibt dies einen gültigen Pfad zurück.

So zu überprüfen, ob eine Datei ein Nachkomme eines Verzeichnisses ist, könnten Sie dies tun:

os.path.commonpath(["/the/dir", os.path.realpath(filename)]) == "/the/dir" 

Im Gegensatz zu commonprefix, brauchen Sie nicht, wenn die Eingänge Schrägstriche haben sich Sorgen zu machen oder nicht hinterher. Der Rückgabewert commonprefix fehlt immer ein Schrägstrich.

Verwandte Themen