На первый взгляд это довольно просто, и я легко мог бы это реализовать. Просто последовательно вызывайте dirname (), чтобы подниматься на каждый уровень пути к файлу и проверять каждый, чтобы убедиться, что это каталог, который мы проверяем.

Но символические ссылки бросают все в хаос. Любой каталог по пути к проверяемому файлу или каталогу может быть символической ссылкой, и любая символическая ссылка может иметь произвольную цепочку символических ссылок на другие символические ссылки. В этот момент мой мозг тает, и я не знаю, что делать. Я пробовал написать код для обработки этих особых случаев, но вскоре он становится слишком сложным, и я предполагаю, что делаю это неправильно. Есть ли достаточно элегантный способ сделать это?

Я использую Python, поэтому было бы круто любое упоминание библиотеки, которая делает это. В противном случае это проблема, не зависящая от языка.

7
mackstann 25 Июл 2010 в 08:30

3 ответа

Лучший ответ

Используйте os.path.realpath и < a href = "https://docs.python.org/3/library/os.path.html#os.path.commonprefix" rel = "nofollow noreferrer"> os.path.commonprefix :

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

os.path.realpath расширит все символические ссылки, а также .. в имени файла. os.path.commonprefix немного непостоянен - он на самом деле не проверяет пути, а только простые строковые префиксы, поэтому вы должны убедиться, что ваш каталог заканчивается разделителем каталогов. Если вы этого не сделаете, будет заявлено, что /the/dirtwo/filename также находится в /the/dir

9
Flimm 20 Июн 2016 в 13:06

Другой способ сделать это в Python 3 - использовать pathlib :

from pathlib import Path

is_descendant = Path("/the/dir") in Path(filename).resolve().parents

См. Документацию по Path.resolve() и < a href = "https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.parents" rel = "nofollow noreferrer"> Path.parents .

0
Flimm 2 Июл 2020 в 08:18