Скрипт Bash для создания символических ссылок на общие библиотеки - PullRequest
6 голосов
/ 20 января 2009

Я думаю, что этот вопрос довольно легок для вас, монстры скриптовых оболочек.

Я ищу самый элегантный и кратчайший способ создания символических ссылок на общие библиотеки для Unix с помощью сценария оболочки bash.

Мне нужно начать со списка файлов общей библиотеки, таких как «libmythings.so.1.1, libotherthings.so.5.11», получить символические ссылки, такие как:

libmythings.so -> libmythings.so.1 -> libmythings.so.1.1
libotherthings.so -> libotherthings.so.5 -> libotherthings.so.5.11

Файлы библиотеки находятся в каталоге, который содержит другие файлы, такие как другие сценарии оболочки.

РЕДАКТИРОВАТЬ : Ну, "ldconfig -nN." может работать нормально, но мне также нужна ссылка без добавленного после ".so" основного номера библиотеки, по крайней мере, одной из библиотек, поскольку одна или несколько библиотек являются точками входа вызовов JNI из Java, поэтому когда библиотека создается с помощью System.loadlibrary ("имя_библиотеки"), она ожидает библиотеку с именем "имя_библиотеки.so", а не "имя_библиотеки.so.X".

Решение, использующее только ldconfig -nN, могло бы работать, если бы был обходной путь для части Java.

Ответы [ 3 ]

13 голосов
/ 20 января 2009

Я считаю, ldconfig - это стандартный инструмент, который делает это.

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

РЕДАКТИРОВАТЬ Да, если вы запустите

ldconfig -v 

Вы увидите, что он генерирует все ссылки на основе внутренних компонентов библиотеки.

ldconfig /path/to/dir 

Будет создавать ссылки только для файлов в этом каталоге

Примечание, однако, я играл с ним, и похоже, что он не всегда создает .so $, просто .so. {Major}

Я не уверен, как работают его внутренние компоненты, но я знаю:

lib # rm libmagic.so
lib # rm libmagic.so.1
lib # ldconfig 
lib # file libmagic.so.1   
libmagic.so.1: symbolic link to `libmagic.so.1.0.0'
lib # file libmagic.so 
libmagic.so: cannot open `libmagic.so' (No such file or directory)

Так, что определяет, как это работает, для меня загадка

Редактировать При дальнейшем исключении файлы .la не влияют на поведение.

Поле имени «SO» указывает, как будет вызываться символическая ссылка.

И будет только один.

0x000000000000000e (SONAME) Имя библиотеки библиотеки: [libmagix.so]

Это после взлома кода и замены ".1" пробелами.

ldconfig сгенерировал "libmagic.so" (да, включая пробелы)

6 голосов
/ 20 января 2009
for baselib in "$@"
do
     shortlib=$baselib
     while extn=$(echo $shortlib | sed 's/\.[0-9][0-9]*$//')
           [ -n "$extn" ]
     do
         shortlib=$(basename $shortlib $extn)
         ln -s $baselib $shortlib
     done
done

Я обманул - все ссылки идут в базовую библиотеку (libmythings.so.1.1); если вы действительно хотите создать цепочку, то вам нужно:

for baselib in "$@"
do
     shortlib=$baselib
     while extn=$(echo $shortlib | sed 's/\.[0-9][0-9]*$//')
           [ -n "$extn" ]
     do
         shorterlib=$(basename $shortlib $extn)
         ln -s $shortlib $shorterlib
         shortlib=$shorterlib
     done
done           

Осторожно - непроверенный код.


Гордыня предшествует Немезиде.

Пришел комментарий, что приведенный выше код не работает - и комментарий правильный. Фиксированная версия с тестом на месте:

set -- libname.so.5.1.1

for baselib in "$@"
do
    shortlib=$baselib
    while extn=$(echo $shortlib | sed -n '/\.[0-9][0-9]*$/s/.*\(\.[0-9][0-9]*\)$/\1/p')
          [ -n "$extn" ]
    do
        shortlib=$(basename $shortlib $extn)
        echo ln -s $baselib $shortlib
    done
done

Изменение в команде sed. Эта версия по умолчанию ничего не печатает (-n), сопоставляет только строки, заканчивающиеся точкой, за которой следуют цифры, а затем удаляет все, кроме этого суффикса, и печатает то, что осталось для назначения extn. С поправками скрипт генерирует вывод ниже. Удалите эхо, чтобы заставить его выполнять команды связи.

ln -s libname.so.5.1.1 libname.so.5.1
ln -s libname.so.5.1.1 libname.so.5
ln -s libname.so.5.1.1 libname.so

Сценарий иллюстрирует интересный и часто упускаемый из виду сценарий оболочки: последовательность операций в блоке условий некоторого времени не обязательно должна быть единственной командой. Статус строки с операцией редактирования не влияет на успешность теста в целом; Состояние выхода последней команды, '[ -n "$extn" ]', контролирует, продолжается ли цикл.

3 голосов
/ 16 ноября 2011

Получено из сценария от Джонатана Леффлера (я добавил это как сценарий под названием «liblinks» в моем ~ / bin)

#!/bin/bash
# liblinks - generate symbolic links 
# given libx.so.0.0.0 this would generate links for libx.so.0.0, libx.so.0, libx.so
#

# By adding sudo to the ls command, we get permission to do the linking (or get an empty list)
LIBFILES=`sudo ls lib*.so.*`
for FILE in $LIBFILES;
   do
   echo $FILE
    shortlib=$FILE
    basename=$FILE
    while extn=$(echo $shortlib | sed -n '/\.[0-9][0-9]*$/s/.*\(\.[0-9][0-9]*\)$/\1/p')
          [ -n "$extn" ]
    do
        shortlib=$(basename $shortlib $extn)
        sudo ln -fs $basename $shortlib
        basename=$shortlib
    done

   done
...