パスを使用するためにインストールする必要があるすべての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これで、上記のコマンドを実行してからldd各パスでコマンドを実行し、その共有ライブラリを反復処理するスクリプトを作成できます( locatefor のようにパスがない場合は、を使用する必要がある場合がありますlinux-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")

依存関係ツリー

関連情報