Найти только пункт назначения символьной ссылки

Вопрос или проблема

Для использования в shell-скрипте я ищу способ в командной строке, чтобы получить назначение символической ссылки. Ближе всего я подошел к этому с помощью stat -N src, который выводит src -> dst. Конечно, я мог бы разбить вывод и получить dst, но мне интересно, существует ли какой-то прямой способ получить назначение.

Другой вариант — использовать специально разработанную команду readlink, если она доступна.

Например:

$ readlink -f `command -v php`
/usr/bin/php7.1

Флаг -f имеет такую функциональность: “канонизировать, следуя каждой символической ссылке в каждом компоненте данного имени рекурсивно; все, кроме последнего компонента, должны существовать”. Это делает вывод этой команды потенциально отличным от stat -c'%N' src, который не следует за каждой символической ссылкой.

На Mac OS X и FreeBSD/NetBSD/и т. д. это:

stat -f %Y <filename>

Более универсально, я думаю, решение такое (stat –printf=%N использует странные кавычки):

ls -l b | sed -e 's/.* -> //'

Пример:

# ln -s a b
# stat -f %Y b
a

Еще один способ:

# find b -maxdepth 0 -printf %l
a#

Последняя строка искажена, так как не имеет новой строки, но это нормально, если вам нужно получить результат в переменной, например, так

# f=$(find b -maxdepth 0 -printf %l)
# echo $f
a

Флаг -maxdepth нужен, чтобы предотвратить спуск find в каталоги, если b оказывается каталогом.

Это можно сделать с помощью GNU find: find src -prune -printf "%l\n".

Команда realpath из пакета coreutils,

как указано на странице руководства по команде readlink.


например:

realpath /bin/python

выводит

/usr/bin/python2.7

на моей машине.

На системе, где у меня нет команд readlink или stat, но есть Python 2.x, я использую короткий скрипт:

#!/usr/bin/env python

import os, sys

if __name__ == "__main__":
    src = sys.argv[1]
    target = os.readlink(src)
    if not os.path.isabs(target):
            target = os.path.abspath(os.path.join(os.path.dirname(src), target))
    print target

Учтите, что в отличие от readlink -f это может следовать только по одному уровню символической ссылки.

Портативная чистая Bash realpath

bash_realpath() {
  # выводит разрешенный путь
  # @параметры
  # 1: путь для разрешения
  # @возвращает
  # &1: разрешенный путь ссылки

  local path="${1}"
  while [[ -L ${path} && "$(ls -l "${path}")" =~ -\>\ (.*) ]]
  do
    path="${BASH_REMATCH[1]}"
  done
  echo "${path}"
}

Портативно: безуспешно, кроме использования эвристик для разбора вывода ls -l, или использовать perl -le 'print readlink("some-file")'

на некоторых системах есть команда readlink, на некоторых с опцией -f для получения абсолютного пути.

Есть различные реализации команды stat как обертки для системных вызовов stat/lstat. GNU реализация не полезна в этом отношении, но встроенная в zsh более полезна:

zmodload zsh/stat
stat +link the-link

Тем не менее, с помощью zsh, вы можете получить абсолютный путь к файлу (удаляет каждый компонент символической ссылки) с помощью модификатора :A (применяется к расширению переменных, расширению истории и глоббингу:

~$ gstat -c %N b
`b' -> `a'
~$ var=b
~$ echo $var:A
/home/me/a
~$ echo b(:A)
/home/me/a
~$ echo ?(@:A)
/home/me/a

Добавил версию на чистом sh, надеясь, что она будет более портативной, если bash не установлен:

$ cat ./realpath.sh
#!/usr/bin/env sh

bash_realpath() {
  # выводит разрешенный путь
  # @параметры
  # 1: путь для разрешения
  # @возвращает
  # &1: разрешенный путь ссылки

  for path;do
    while [ -L "${path}" ]
    do
      path="$(\ls -l "${path}" | awk '{print $NF}')"
    done
    which "${path}"
  done
}

bash_realpath "$@"

Пример использования :

$ ./realpath.sh $(which gcc python)
/usr/bin/x86_64-linux-gnu-gcc-6
/usr/bin/python2.7

.

Ответ или решение

Определение назначения символической ссылки в скрипте

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

Теория

Символическая ссылка (или symlink) — это специальный тип файла, который указывает на другой файл или каталог. В отличие от жестких ссылок, символические ссылки являются отдельными файлами. Они могут указывать на любые файлы или каталоги, включая те, которые находятся на других файловых системах. Самый важный аспект символической ссылки заключается в том, что она хранит путь к целевому объекту, но не обладает его содержимым.

Определение целевого объекта символической ссылки является часто встречающейся задачей в различных сценариях автоматизации и администрирования систем. Она может быть критически важной при отладке, миграции данных и других операциях, связанных с поддержанием целостности данных.

Примеры

  1. Команда readlink: Один из наиболее простых способов выяснить, куда указывает символическая ссылка — это использовать утилиту readlink. Например:

    readlink symlink_name

    Если необходимо получить полный канонический путь, включая все промежуточные символические ссылки, используется опция -f:

    readlink -f symlink_name

    Однако стоит отметить, что опция -f недоступна в некоторых системах, таких как macOS по умолчанию.

  2. Команда stat: В UNIX-системах команда stat позволяет получать информацию о файле или файловой системе, включая данные о символических ссылках. На разных операционных системах синтаксис этой команды может варьироваться:

    • Для GNU систем:

      stat -c %N symlink_name
    • В macOS и BSD-подобных системах:

      stat -f %Y symlink_name
  3. Использование find: Эта команда также может использоваться для определения цели символической ссылки:

    find symlink_name -maxdepth 0 -printf %l

    Важно отметить использование -maxdepth 0 для избежания погружения в каталоги, если symlink указывает на директорию.

  4. Реализация на Python: На системах, где нет доступа к readlink или stat, можно воспользоваться Python-скриптом:

    #!/usr/bin/env python
    
    import os
    import sys
    
    if __name__ == "__main__":
        src = sys.argv[1]
        target = os.readlink(src)
        if not os.path.isabs(target):
            target = os.path.abspath(os.path.join(os.path.dirname(src), target))
        print(target)

Этот скрипт определяет путь к файлу-цели, даже если символическая ссылка является относительной.

Применение

Выбор конкретного инструмента зависит от контекста использования. Для системных администраторов, работающих преимущественно в среде Linux, readlink и stat будут наиболее предпочтительными инструментами благодаря своей простоте и быстродействию. В случаях, когда необходима кроссплатформенная совместимость, Python-скрипт может стать незаменимым помощником.

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

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

Оцените материал
Добавить комментарий

Капча загружается...