2010-07-25 12 views
7

Na pierwszy rzut oka jest to dość proste, a ja sam mógłbym je łatwo wdrożyć. Wystarczy kolejno wywołać dirname(), aby przejść na wyższy poziom na ścieżce pliku i sprawdzić, czy jest to katalog, który sprawdzamy.Jak mogę sprawdzić, czy plik jest potomkiem danego katalogu?

Ale dowiązania symboliczne rzucają całość w chaos. Każdy katalog znajdujący się na ścieżce sprawdzanego pliku lub katalogu może być dowiązaniem symbolicznym, a każde dowiązanie symboliczne może mieć dowolny łańcuch dowiązań symbolicznych do innych dowiązań symbolicznych. W tym momencie mój mózg topi się i nie jestem pewien, co robić. Próbowałem napisać kod, aby poradzić sobie z tymi szczególnymi przypadkami, ale wkrótce staje się zbyt skomplikowany i zakładam, że robię to źle. Czy istnieje dość elegancki sposób na zrobienie tego?

Używam Pythona, więc każda wzmianka o bibliotece, która to robi, byłaby fajna. W przeciwnym razie jest to dość neutralny problem językowy.

Odpowiedz

8

Zastosowanie os.path.realpath i os.path.commonprefix:

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

os.path.realpath poszerzy żadnych dowiązania jak .. w nazwie pliku. os.path.commonprefix jest nieco zmienny - nie testuje właściwie ścieżek, tylko zwykłe przedrostki smyczkowe, więc powinieneś upewnić się, że katalog kończy się separatorem katalogu. Jeśli nie, to zastrzeżenia /the/dirtwo/filename jest również w /the/dir

+0

Może przypadki skrajne są w mojej głowie. Mógłbym przysiąc, że dowiązanie symboliczne powoduje, że takie podejście w niektórych przypadkach nie udaje się, ale nie mogę wymyślić przykładów, które by to udowodniły. Czuję, że walczę z duchem ... – mackstann

+1

Ponieważ każdy hierarchiczny system plików, jaki wymyślę, wymaga pojedynczego, unikalnego, kanonicznego, prawdziwego nazwanego katalogu, to faktycznie działa. Chociaż może być sprzeczne z intuicją, że można dostać się z miejsca na miejsce, w katalogach "prawdziwy rodzic" musi być prawdziwy lub zły. – msw

+0

Cóż, to dobra wiadomość, aby to usłyszeć. Teraz wystarczy sprawdzić cztery przypadki (realpath i non-realpath dla obu katalogów i plików). Dzięki! – mackstann

1

Python 3.5 posiada użyteczną funkcję os.path.commonpath:

Return najdłuższy wspólny sub-path każdej ścieżki w ścieżkach sekwencji. Podnieście wartość ValueError, jeśli ścieżki zawierają zarówno bezwzględne i względne nazwy ścieżek, jak i ścieżki są puste. W przeciwieństwie do commonprefix(), ta zwraca poprawną ścieżkę.

Tak, aby sprawdzić, czy plik jest potomkiem katalogu, można to zrobić:

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

przeciwieństwie commonprefix, nie trzeba się martwić, jeśli dane wejściowe są końcowe ukośniki czy nie. Zwracana wartość commonprefix zawsze nie zawiera końcowego ukośnika.

Powiązane problemy