Как я могу проверить, что данный обычный файл пути f является потомком каталога пути d . Если бы не символические ссылки, я бы просто проверил, является ли d (с завершающим слешем) префиксом к f .
Теперь с символическими ссылками это немного усложняется, так как я мог найти физические пути предков f и сравнить каждый из них с физическим путем d . Тем не менее, я считаю, что для этого может быть полезна пользовательская утилита.
2 ответа
- Если предки файла определены как каталог, содержащий его, и предки этого каталога, т. Е. Потомки каталога являются его записями и (для записей, которые являются каталогами) их собственными потомками: - Предполагая, что - $fявляется путем к обычному файлу (а не путем символьной ссылки), вы можете найти «реальный» каталог, содержащий его, с помощью команды- $(cd -- "$(dirname "$f")" && command -p pwd). Аналогичным образом найдите «реальное» местоположение каталога- $dс помощью- $(cd -- "$d" && command -p pwd). В bash/ksh/zsh вы можете заменить- command -p pwdна- pwd -P.- Если - $fможет быть символической ссылкой, это более сложно. В некоторых системах есть команда- readlink, например, вы можете использовать- $(dirname "$(readlink -f -- "$f"))с относительно свежим GNU coreutils, но обратите внимание, что есть другие системы с несовместимой командой- readlinkили ее нет все.- Обратите внимание, что файл может быть перемещен между временем проверки и временем использования результата. Есть также угловые случаи, когда вопрос не имеет четкого ответа да / нет, например, когда путь от каталога до файла проходит точку монтирования. - Если вам нужно знать, какая файловая система - $fвключена , запустите- df "$f".
- Если потомки каталога - $dопределены как файлы, которым можно дать имя в форме- $d/x1/x2/.../xnгде- xiможет быть каталогами или символическими ссылками:- Тестирование этого свойства требует обхода всего дерева каталогов с корнем в - $d, следуя всем символическим ссылкам. Следующая команда должна сделать это (предупреждение, введенное непосредственно в браузер; требует GNU find):- [ -n "$(find -L "$d" -samefile "$f" -print -quit)" ]- Если - $fимеет жесткие ссылки, он может получить доступ к файлу- $fчерез другое имя. Если вам требуется, чтобы файл находился под именем- $f, он становится более сложным; Вот попытка (опять же, набранная прямо в браузере; требует GNU find и GNU grep; не предполагает никаких новых строк в именах файлов):- f_directory="$(cd -- "$(dirname "$f")" && command -p pwd)" f_truename="$f_directory/$(basename "$f")" [ -n "$(find -L "$(cd "$d" && command -p pwd)" -exec readlink -f \; | grep -F -q -x "$f_truename")" ]- Независимо от того, какое именно определение вы выберете, это свойство не очень надежно, поскольку вы можете изменить его значение, добавив или удалив символическую ссылку глубоко под - $d.
Моя команда 'ls' имеет флаг "--dereference-command-line-symlink-to-dir", который показывает полный путь к файлу. Это 'ls' из GNU coreutils 6.9.
