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 ldd
vejo:
> 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 rpm
comando acima e, em seguida, o ldd
comando em cada caminho e itere sobre as bibliotecas compartilhadas (pode ser necessário usar locate
porque às vezes não há caminho, como for linux-vdso.so.1
). Mas:
- Não é recomendado usar
ldd
. - A análise da
ldd
saída é muito feia.
Agora, eu vi um relacionadotemasobre o assunto. Eu poderia usar, readelf
mas 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 é:
- Execute
/bin/rpm -qf --queryformat "[%{NAME}]\n" $path
e obtenha o nome do pacote (marcado com$package)
. Adicione-o também à lista de pacotes. - Execute
rpmdep.pl $package
) e adicione todos os pacotes à lista. - Execute
ldd $path
e para cada linha:- se houver um caminho (como
libsqlite3.so.0 => /usr/lib64/libsqlite3.so.0
), volte para a etapa 1 com/usr/lib64/libsqlite3.so.0
. - se não houver caminho (como
linux-vdso.so.1
), tente localizá-lo (usandolocate
o comando) e, se encontrado, volte para a etapa 1 com o caminho obtido.
- se houver um caminho (como
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.