해당 경로를 사용하기 위해 설치해야 하는 모든 OS 패키지를 검색합니다.

해당 경로를 사용하기 위해 설치해야 하는 모든 OS 패키지를 검색합니다.

경로가 주어지면 이를 사용하기 위해 설치해야 하는 모든 OS 패키지를 검색하고 싶습니다. 예를 들어:

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

를 사용하려면 필수 OS 패키지를 설치해야 한다는 의미입니다 /sadd/python/lib/python3.7/lib-dynload/_sqlite3.cpython-37m-x86_64-linux-gnu.so.

rpm이제 위의 명령을 실행한 다음 각 경로에서 명령을 실행하고 해당 공유 라이브러리를 반복하는 스크립트를 만들 수 있습니다 ( for와 같은 경로가 없는 경우가 있기 때문에 ldd사용해야 할 수도 있음 ). 하지만:locatelinux-vdso.so.1

  1. 를 사용하는 것은 권장되지 않습니다 ldd.
  2. 출력 구문 분석은 ldd매우 추악합니다.

지금 관련글을 봤는데주제이 문제에. 사용할 수는 있지만 readelf동일한 문제가 있습니다.

특정 경로에 필요한 모든 OS 패키지를 검색하는 더 나은 솔루션이 있습니까? 나도 사용하고 있어요rpmdep.pl그러나 패키지 이름을 얻고 모든 패키지 종속성을 반환할 것으로 예상합니다. 따라서 현재 내 알고리즘은 다음과 같습니다.

  1. 실행 /bin/rpm -qf --queryformat "[%{NAME}]\n" $path하여 패키지 이름( 로 표시됨)을 가져옵니다 $package). 또한 패키지 목록에도 추가합니다.
  2. )을 실행 rpmdep.pl $package하고 모든 패키지를 목록에 추가합니다.
  3. ldd $path각 줄에 대해 다음을 실행합니다 .
    1. 경로(예: )가 있으면 를 libsqlite3.so.0 => /usr/lib64/libsqlite3.so.0사용하여 1단계로 돌아갑니다 /usr/lib64/libsqlite3.so.0.
    2. 경로가 없으면(예 : 명령을 linux-vdso.so.1사용하여) 경로를 찾아보고 locate, 찾은 경우 얻은 경로를 사용하여 1단계로 돌아갑니다.

그렇게 하면 경로에 필요한 모든 OS 패키지를 수집할 수 있습니다. 꽤 잘 작동하지만 이 작업을 해결하기 위한 더 나은/깨끗한 접근 방식을 찾고 있습니다. 그리고 제가 제안한 알고리즘에 대해 어떻게 생각하시나요?

중요한 경우 OpenSUSE를 사용하고 있습니다.

답변1

$ cat installer.sh
#! /bin/bash

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

종속성 트리

관련 정보