Вы не должны ожидать, что эта переменная изменится. Это используется для хранения пути к оболочке по умолчанию, т.е. того, сохраненного в базе данных пароля, не, которые окружают, Вы в настоящее время работаете.
Хорошо, после того, как еще некоторые думали, что я думаю, что у меня есть ясное решение.
Критическое понимание то, что, если каждая ссылка, которая является частью пути, решает к чему-то, затем вся твердость пути. Или наоборот, если путь не решает затем, должна быть определенная символьная ссылка, которая требует пересечения, которое не решает.
При размышлении об этой проблеме ранее я использовал алгоритм, который пересек элементы пути, начинающего с корня, и когда это встретилось с символьной ссылкой, это заменило тот элемент пути содержанием символьной ссылки и затем продолжило пересекать. Так как этот подход не помнит, какая символьная ссылка он в настоящее время разрешает, что не может обнаружить, когда это находится в цикле неразрешения.
Если алгоритм отслеживает, которой символьной ссылки он в настоящее время решает (или который символьные ссылки в случае рекурсивных ссылок), он может обнаружить, если он пытается разрешить ссылку снова рекурсивно, которую это все еще занято, разрешая.
Алгоритм:
initialize `location` to the current working directory
initialize `link_contents` to the path we want to resolve
initialize `active_symlinks` to the empty set
def resolve_symlink(location, link_contents, active_symlinks) :
loop forever:
next_location = location / [first element of link_contents]
see if next_location is a symlink.
if so:
if next_location in active_symlinks: abort, we have a loop
location = resolve_symlink(location, readlink(next_location), active_symlinks ∪ {next_location})
else:
location = next_location
strip first element of link_contents
if link_contents is empty:
return location
править:
У меня есть рабочая реализация этого в Python в https://bitbucket.org/JanKanis/python-inotify/src/853ed903e870cbfa283e6ce7a5e41aeffe16d4e7/inotify/pathresolver.py? at=pathwatcher.
Я не полностью понимаю то, что Вы спрашиваете. Если я не знал ничего лучшего, я думаю, что Вы спрашивали, был ли способ обнаружить это в то время как посреди контакта с файлом. Я не полагаю, что это возможно.
Единственный метод, из которого я могу забеременеть, делает находку, где Вы конкретно начинаете просматривать конкретное ответвление в дереве каталогов.
$ tree
.
`-- a
`-- b
|-- c
| `-- d
| `-- e -> ../../../../a/b
`-- e -> e
5 directories, 1 file
find
команда обнаружит этот цикл, но не действительно скажет Вам много об этом.
$ find -L . -mindepth 15
find: File system loop detected; `./a/b/c/d/e' is part of the same file system loop as `./a/b'.
find: `./a/b/e': Too many levels of symbolic links
Я произвольно выбрал 15 уровней, чтобы заблокировать любой вывод, отображаемый find
. Можно однако отбросить тот переключатель (-mindepth
) если Вы не заботитесь об отображаемом дереве каталогов. find
команда все еще обнаруживает цикл и остановки:
$ find -L .
.
./a
./a/b
./a/b/c
./a/b/c/d
find: File system loop detected; `./a/b/c/d/e' is part of the same file system loop as `./a/b'.
find: `./a/b/e': Too many levels of symbolic links
Кстати, если Вы хотите переопределить значение по умолчанию MAXSYMLINKS
который является, по-видимому, 40 на Linux (более новый 3.x версии ядра), Вы видите это названные Вопросы и ответы U&L: Как Вы увеличиваете MAXSYMLINKS.
Существует инструмент, который специалисты по обслуживанию FTP-сайта могли использовать названный symlinks
который поможет выставить проблемы с инструментом долго или повисшими деревьями, которые были вызваны символьными ссылками.
В определенных случаях symlinks
инструмент мог использоваться для удаления предлагаемых каналов также.
$ symlinks -srv a
lengthy: /home/saml/tst/99159/a/b/c/d/e -> ../../../../a/b
dangling: /home/saml/tst/99159/a/b/e -> e
glibc библиотека надеется предлагать некоторые функции C вокруг этого, но я не полностью знаю их роли или как на самом деле использовать их. Таким образом, я могу только просто указать на них Вам.
Страница справочника, man symlink
показывает функциональное определение для вызванной функции symlink()
. Описание идет как это:
символьная ссылка () создает символьную ссылку, названную newpath, который содержит строку oldpath.
Одно из состояний ошибки, которые возвращает эта функция:
С ELOOP Слишком много символьных ссылок встретились в разрешении newpath.
Я также направлю Вас к странице справочника, man path_resolution
который обсуждает, как Unix определяет пути к объектам на диске. Конкретно этот абзац.
If the component is found and is a symbolic link (symlink), we first
resolve this symbolic link (with the current lookup directory as starting
lookup directory). Upon error, that error is returned. If the result is
not a directory, an ENOTDIR error is returned. If the resolution of the
symlink is successful and returns a directory, we set the current lookup
directory to that directory, and go to the next component. Note that the
resolution process here involves recursion. In order to protect the
kernel against stack overflow, and also to protect against denial of
service, there are limits on the maximum recursion depth, and on the maximum
number of symbolic links followed. An ELOOP error is returned when the
maximum is exceeded ("Too many levels of symbolic links").
Python имеет функцию, вызванную networkx.simple_cycles (), который может использоваться для этого. Но да это должно было бы считать каждый файл в системе.
>>> import networkx as nx
>>> G = nx.DiGraph()
>>> G.add_edge('A', 'B')
>>> G.add_edge('B', 'C')
>>> G.add_edge('C', 'D')
>>> G.add_edge('C', 'A')
>>> nx.simple_cycles(G)
[['A', 'B', 'C', 'A']]
В статической системе (т.е. когда никакие изменения не происходят), да, существует алгоритм. Существует конечное число символьных ссылок, таким образом, они составляют конечный график, и циклы обнаружения являются финитарным процессом.
В живой системе нет никакого способа обнаружить циклы, потому что символьные ссылки могут измениться, в то время как детектор цикла работает. Чтение каждой символьной ссылки является атомарным, но переходить по символьной ссылке не. Если некоторые символьные ссылки продолжают изменяться, в то время как ядро делает обход, оно могло закончиться на бесконечном пути, включающем отличные ссылки.
Почти я могу сказать от рассмотрения текущих источников ядра Linux, все ядро делает, проводят подсчет того, сколько ссылок это сопровождается, и это ошибки, если это больше, чем некоторое число. Посмотрите строку 1330 в namei.c для комментария, и nested_symlink()
функция. Макрос ELOOP (код ошибки, возвращенный из a read(2)
системный вызов этой ситуации), обнаруживается во многих местах в том файле, таким образом, это не может быть столь просто, как, считая ссылки сопровождаемыми, но это уверено, на что это похоже.
Существует много алгоритмов для нахождения "циклов" в связанных списках (алгоритм обнаружения цикла Floyd) или в ориентированных графах. Это не ясно мне, какой необходимо было бы сделать для обнаружения фактического "цикла" или "цикла" в конкретном пути. В любом случае алгоритмы могли занять много времени для выполнения, таким образом, я предполагаю, что просто подсчет количества перешедших символьных ссылок получает Вас 90% пути к Вашей цели.
Создайте список со всеми символическими ссылками/файлами, которые вы посещаете, чтобы при переходе по первой символической ссылке вы добавляли ее в список. Если символическая ссылка указывает на файл в списке (, то есть файл, который вы уже посетили ), вы знаете, что существует цикл