Detecte todos os pacotes do sistema operacional que precisam ser instalados para usar o caminho

Detecte todos os pacotes do sistema operacional que precisam ser instalados para usar o caminho

Dado um caminho, quero detectar todos os pacotes do sistema operacional que precisam ser instalados para usá-lo. Por exemplo:

> /bin/rpm -qf --queryformat "[%{NAME}]\n" /usr/bin/tcsh
tcsh

Às vezes não funciona. Por exemplo:

> /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

Mas olhando para a saída de lddvejo:

> 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)

Eu vejo que tem /usr/lib64/libsqlite3.so.0. Então eu posso fazer:

> /bin/rpm -qf --queryformat "[%{NAME}]\n" /usr/lib64/libsqlite3.so.0
libsqlite3-0

Significa que há um pacote de sistema operacional necessário que deve ser instalado para usar o /sadd/python/lib/python3.7/lib-dynload/_sqlite3.cpython-37m-x86_64-linux-gnu.so.

Agora, posso criar um script que execute o rpmcomando acima e, em seguida, o lddcomando em cada caminho e itere sobre as bibliotecas compartilhadas (pode ser necessário usar locateporque às vezes não há caminho, como for linux-vdso.so.1). Mas:

  1. Não é recomendado usar ldd.
  2. A análise da lddsaída é muito feia.

Agora, eu vi um relacionadotemasobre o assunto. Eu poderia usar, readelfmas o mesmo problema.

Existe uma solução melhor para detectar todos os pacotes de sistema operacional necessários para um determinado caminho? Eu também estou usandorpmdep.plmas espera obter um nome de pacote e retornar todas as dependências do pacote. Então, por enquanto, meu algoritmo é:

  1. Execute /bin/rpm -qf --queryformat "[%{NAME}]\n" $pathe obtenha o nome do pacote (marcado com $package). Adicione-o também à lista de pacotes.
  2. Execute rpmdep.pl $package) e adicione todos os pacotes à lista.
  3. Execute ldd $pathe para cada linha:
    1. se houver um caminho (como libsqlite3.so.0 => /usr/lib64/libsqlite3.so.0), volte para a etapa 1 com /usr/lib64/libsqlite3.so.0.
    2. se não houver caminho (como linux-vdso.so.1), tente localizá-lo (usando locateo comando) e, se encontrado, volte para a etapa 1 com o caminho obtido.

Dessa forma, coleto todos os pacotes de sistema operacional necessários para um caminho. Funciona muito bem, mas estou procurando uma abordagem melhor/limpa para resolver essa tarefa. Além disso, o que você acha do meu algoritmo sugerido?

Estou usando o OpenSUSE, se isso for importante.

Responder1

$ cat installer.sh
#! /bin/bash

mkdir -p /tmp/testdir
test -e "$1" || exit 1
zypper --installroot /tmp/testdir install $(rpm -qf "$1")

Árvore de dependência

informação relacionada