Как я могу узнать, является ли относительная символьная ссылка внутренней к определенному поддереву или нет?

Можно вставить его Ваш .bash_profile, который выполняется каждый раз, когда Вы входите в систему.

Или, если это - псевдоним для долгой команды, можно вставить это Ваш .bash_aliases файл в соответствии с Вашим корневым каталогом:

alias short_version="very long command here"
7
09.01.2014, 01:38
3 ответа

Я не думаю, что существует такая утилита. С GNU readlink, Вы могли сделать что-то как:

is_in() (
  needle=$(readlink -ve -- "$1" && echo .) || exit
  haystack=$(readlink -ve -- "$2" && echo .) || exit
  needle=${needle%??} haystack=${haystack%??}
  haystack=${haystack%/} needle=${needle%/}
  case $needle in
    ("$haystack" | "$haystack"/*) true;;
    (*) false;;
  esac
)

Это разрешает все символьные ссылки для окончания с каноническим полным путем и для иглы и для стога сена.

Объяснение

  • Мы получаем канонический полный путь и иглы и стога сена. Мы используем -e вместо -f поскольку мы хотим удостовериться, что файлы существуют. -v опция дает сообщение об ошибке, если к файлам нельзя получить доступ.
  • Как всегда, -- должен использоваться для маркировки конца опций и заключающий в кавычки, поскольку мы не хотим вызывать split+glob оператор здесь.
  • Замена команды в подобных Границе оболочках имеет ошибку, в которой она удаляет весь символ новой строки из конца вывод команды, не только тот, добавленный командами для окончания последней строки. То, что это означает, то, что для файла как /foo<LF><LF>, $(readlink -ve -- "$1") возвратился бы /foo. Общее обходное решение для этого должно добавить символ non-LF (здесь .) и полоса это и дополнительный символ LF, добавленный readlink с var=${var%??} (удалите последние два символа).
  • Игла расценивается как являющийся в стоге сена, если это - стог сена или если это - стог сена/что-то. Однако это не работало бы, если бы стог сена был / (/etc для вместо этого не //something). / часто потребности, которые будут рассматривать особенно, потому что, в то время как / и /xx имейте то же количество наклонных черт, каждый - уровень выше другого.

    Один способ обратиться к нему состоит в том, чтобы заменить / с пустой строкой, которая является, покончили var=${var%/} (единственный путь, заканчивающийся / это readlink -e /, так удаление запаздывания / изменяется / к пустой строке).

Для канонизации путей к файлам Вы могли использовать функцию помощника.

canonicalize_path() {
  # canonicalize paths stored in supplied variables. `/` is returned as 
  # the empty string.
  for _var do
    eval '
      '"$_var"'=$(readlink -ve -- "${'"$_var"'}" && echo .) &&
      '"$_var"'=${'"$_var"'%??} &&
      '"$_var"'=${'"$_var"'%/}' || return
  done
}

is_in() (
  needle=$1 haystack=$2
  canonicalize_path needle haystack || exit
  case $needle in
    ("$haystack" | "$haystack"/*) true;;
    (*) false;;
  esac
)
5
27.01.2020, 20:19
  • 1
    я нашел изучение этого сообщения очень поучительным. Я могу задать Вам несколько вопросов? Есть ли любое значение в факте это в needle=${needle%??} haystack=${haystack%??} needle с переменной имеют дело с первым, тогда как в следующей строке это наоборот? Кроме того, каким образом Ваш return операторы явно не возвращают ненулевое значение (для указания на ошибку)? Последний: имело бы смысл факторизовать все преобразование (вызов к readlink, плюс два суффиксных усечения) к отдельному _canonicalize_path функция помощника? –  kjo 22.02.2016, 14:28
  • 2
    @kjo, 1) никакое значение 2) return возвраты по умолчанию с состоянием последней команды. С || return, это позволяет возвращать состояние в соответствии с провальным приложением. 3) уверенный, но получающаяся функция, вероятно, не будет приятный вид. Я добавлю пример. –  Stéphane Chazelas 22.02.2016, 14:48
  • 3
    Спасибо! я вижу то, что Вы имеете в виду! Не приятный вид вообще. Программирование Shell должно быть самым твердым типом программирования, о котором я знаю... –  kjo 22.02.2016, 15:11

Я решил проблему как это:

echo $abs_link_target | grep -qe "^$containing_dir"

$abs_link_target переменная содержит абсолютный путь к цели символьной ссылки (расширенный через readlink -f). Я затем проверяю, чтобы видеть, соответствует ли начало пути назначения началу $containing_dir

0
27.01.2020, 20:19
  • 1
    Это было бы говорить, что/foobar находится в / нечто –  Stéphane Chazelas 09.01.2014, 10:28
  • 2
    , Это сказало бы, что/abc/d находится в/a.b ($containing_dir взятый в качестве regexp) –  Stéphane Chazelas 09.01.2014, 10:28
  • 3
    Это сказало бы, что / abc находится в /foo<LF>/abc (строки строки образца рассматривают как различные шаблоны для соответствия), –  Stéphane Chazelas 09.01.2014, 10:30
  • 4
    Это сказало бы это /foo<LF>/abc находится в /abc (grep соответствия на каждой строке входа, не целый вход так обычно не может использоваться для соответствия именам файлов). –  Stéphane Chazelas 09.01.2014, 10:55
  • 5
    В зависимости от echo реализация и/или среда, у Вас будут проблемы с именами файлов, содержащими обратные косые черты echo не должен действительно использоваться для обработки произвольных данных –  Stéphane Chazelas 09.01.2014, 10:56

grep -q "^/foo/bar/" <<< "$(readlink -f "anyfile.ext")"

0
27.01.2020, 20:19
  • 1
    Принятие цели anyfile.ext существует и достижим (иначе, readlink -f в противоположность readlink -e не мог бы дать Вам корректный путь), и что получающийся путь не содержит символы новой строки (принимает zsh или bash4 или ksh93m + или выше). Отметьте это если anyfile.ext точки к /foo/bar самостоятельно, это скажет, что это не в. –  Stéphane Chazelas 10.01.2014, 13:56

Теги

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