Учитывая путь, я хочу обнаружить все пакеты ОС, которые необходимо установить, чтобы использовать его. Например:
> /bin/rpm -qf --queryformat "[%{NAME}]\n" /usr/bin/tcsh
tcsh
Иногда это не работает. Например:
> /bin/rpm -qf --queryformat "[%{NAME}]\n" /sadd/python/lib/python3.7/lib-dynload/_sqlite3.cpython-37m-x86_64-linux-gnu.so
file /sadd/python/lib/python3.7/lib-dynload/_sqlite3.cpython-37m-x86_64-linux-gnu.so is not owned by any package
Но, глядя на вывод, ldd
я вижу:
> ldd /sadd/python/lib/python3.7/lib-dynload/_sqlite3.cpython-37m-x86_64-linux-gnu.so
linux-vdso.so.1 (0x00007f11f7ffa000)
libsqlite3.so.0 => /usr/lib64/libsqlite3.so.0 (0x0000711fff7901000)
libpython3.7m.so.1.0 => /usr/pkgs/python3/3.7.4/lib/libpython3.7m.so.1.0 (0x00007ffff7422000)
libpthread.so.0 => /lib64/noelision/libpthread.so.0 (0x00007f11ff7205000)
libc.so.6 => /lib64/libc.so.6 (0x00007f13ff6e60000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007ff126c5c000)
libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007ff216a21000)
libutil.so.1 => /lib64/libutil.so.1 (0x0000711ff681e000)
libm.so.6 => /lib64/libm.so.6 (0x00007fff16521000)
/lib64/ld-linux-x86-64.so.2 (0x00007fff17ddb000)
Я вижу, что он имеет /usr/lib64/libsqlite3.so.0
. Так что я могу сделать:
> /bin/rpm -qf --queryformat "[%{NAME}]\n" /usr/lib64/libsqlite3.so.0
libsqlite3-0
/sadd/python/lib/python3.7/lib-dynload/_sqlite3.cpython-37m-x86_64-linux-gnu.so
Это означает, что для использования . необходимо установить пакет ОС .
Теперь я могу создать скрипт, который запускает указанную выше rpm
команду, а затем ldd
команду по каждому пути и выполняет итерацию по этим общим библиотекам (может потребоваться использовать , locate
потому что иногда нет пути, как для linux-vdso.so.1
). Но:
- Не рекомендуется использовать
ldd
. - Анализ вывода
ldd
довольно уродлив.
Теперь я увидел связанноетемапо этому вопросу. Я мог бы использовать, readelf
но та же проблема.
Есть ли лучшее решение для обнаружения всех требуемых пакетов ОС для заданного пути? Я также используюrpmdep.plно он ожидает получить имя пакета и возвращает все зависимости пакета. Так что на данный момент мой алгоритм такой:
- Запустите
/bin/rpm -qf --queryformat "[%{NAME}]\n" $path
и получите имя пакета (отмечено$package)
. Также добавьте его в список пакетов. - Запустите
rpmdep.pl $package
) и добавьте все пакеты в список. - Запустите
ldd $path
и для каждой строки:- если есть путь (например
libsqlite3.so.0 => /usr/lib64/libsqlite3.so.0
), то вернитесь к шагу 1 с помощью/usr/lib64/libsqlite3.so.0
. - если пути нет (например
linux-vdso.so.1
, ), то попробуйте найти его (используяlocate
команду) и, если найдете, то вернитесь к шагу 1 с полученным путем.
- если есть путь (например
Таким образом я собираю все пакеты ОС, которые требуются для пути. Это работает довольно хорошо, но я ищу лучший/чистый подход к решению этой задачи. Кроме того, что вы думаете о моем предложенном алгоритме?
Если это имеет значение, я использую OpenSUSE.