окружите утилиту, чтобы проверить, является ли каталог предком в файл

Как я могу проверить что данный регулярный файл пути f потомок каталога пути d. Если бы не символьные ссылки я просто проверил бы если d (с запаздывающей наклонной чертой), префикс к f. Теперь с символьными ссылками это становится незначительно более сложным, поскольку я мог найти физические пути предков f и сравните каждого из них к физическому пути d. Однако я полагаю, что могла бы быть утилита пространства пользователя, для которой, там один?

3
задан 23.10.2014, 18:59

2 ответа

  1. Если предки файла определяются как каталог, содержащий его и предки того каталога, т.е. потомки каталога являются его записями и (для записей, которые являются каталогами), их собственные потомки:

    Принятие этого $f путь регулярного файла (а не путь символьной ссылки), можно найти “реальный” каталог, содержащий его с $(cd -- "$(dirname "$f")" && command -p pwd). Точно так же найдите “реальное” местоположение каталога $d с $(cd -- "$d" && command -p pwd). В bash/ksh/zsh можно заменить command -p pwd pwd -P.

    Если $f может быть символьная ссылка, это более сложно. Некоторые системы имеют a readlink команда, например, Вы могли использовать $(dirname "$(readlink -f -- "$f")) с довольно недавним GNU coreutils, но примечанием, что существуют другие системы с несовместимым readlink команда или ни один вообще.

    Обратите внимание, что файл может быть перемещен между временем, Вы осуществляете проверку и время, Вы используете результат. Существуют также угловые случаи, где вопрос не имеет четкого ответа "да"/"нет", такой как тогда, когда путь от каталога до файла пересекает точку монтирования.

    Если все, что Вы хотите знать, который файловая система $f идет, выполненный df "$f".

  2. Если потомки каталога $d определяются как файлы, которым можно дать название формы $d/x1/x2/.../xn где xi могут быть каталоги или символьные ссылки:

    Тестирование этого свойства требует, чтобы обход целого дерева каталогов базировался в $d, переходить по всем символьным ссылкам. Следующая команда должна сделать это (предупреждение, введенное непосредственно в браузер; требует, чтобы GNU нашел):

    [ -n "$(find -L "$d" -samefile "$f" -print -quit)" ]
    

    Если $f имеет жесткие ссылки, это может получить доступ к файлу $f через другое имя. Если Вы требуете, чтобы файл был найден под именем $f, это становится более сложным; вот попытка (снова, введенный непосредственно в браузер; требует, чтобы GNU нашел и 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.

4
ответ дан 08.12.2019, 00:07

Моя команда 'ls' имеет флаг "-dereference-command-line-symlink-to-dir", который показывает полный путь файлу. Этот 'ls' от GNU coreutils 6.9.

1
ответ дан 08.12.2019, 00:07

Теги

Похожие вопросы