Erkennen Sie alle Betriebssystempakete, die installiert werden müssen, um den Pfad verwenden zu können

Erkennen Sie alle Betriebssystempakete, die installiert werden müssen, um den Pfad verwenden zu können

Bei einem vorgegebenen Pfad möchte ich alle Betriebssystempakete ermitteln, die installiert werden müssen, um ihn verwenden zu können. Beispiel:

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

Manchmal funktioniert es nicht. Zum Beispiel:

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

Aber wenn ich mir die Ausgabe anschaue ldd, sehe ich:

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

Ich sehe, dass dies der Fall ist /usr/lib64/libsqlite3.so.0. Ich kann also Folgendes tun:

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

Dies bedeutet, dass zur Verwendung ein erforderliches Betriebssystempaket installiert werden muss /sadd/python/lib/python3.7/lib-dynload/_sqlite3.cpython-37m-x86_64-linux-gnu.so.

Jetzt kann ich ein Skript erstellen, das den obigen rpmBefehl und dann den lddBefehl auf jedem Pfad ausführt und über diese gemeinsam genutzten Bibliotheken iteriert (muss möglicherweise verwendet werden, locateweil manchmal kein Pfad vorhanden ist, z. B. für linux-vdso.so.1). Aber:

  1. Die Verwendung wird nicht empfohlen ldd.
  2. Die Analyse der lddAusgabe ist ziemlich hässlich.

Nun sah ich eine verwandteThemazu dem Thema. Ich könnte es verwenden, readelfaber dasselbe Problem.

Gibt es eine bessere Lösung, um alle erforderlichen Betriebssystempakete für einen bestimmten Pfad zu erkennen? Ich verwende auchrpmdep.plaber es erwartet einen Paketnamen und gibt alle Paketabhängigkeiten zurück. Mein Algorithmus ist also im Moment:

  1. Führen Sie es aus /bin/rpm -qf --queryformat "[%{NAME}]\n" $pathund rufen Sie den Paketnamen ab (mit markiert) $package). Fügen Sie es auch zur Paketliste hinzu.
  2. Führen Sie den Befehl rpmdep.pl $package) aus und fügen Sie alle Pakete zur Liste hinzu.
  3. Führen Sie ldd $pathfür jede Zeile Folgendes aus:
    1. Wenn ein Pfad vorhanden ist (wie libsqlite3.so.0 => /usr/lib64/libsqlite3.so.0), gehen Sie mit zurück zu Schritt 1 /usr/lib64/libsqlite3.so.0.
    2. wenn kein Pfad vorhanden ist (wie linux-vdso.so.1), versuchen Sie, ihn zu lokalisieren (mit locatedem Befehl), und wenn er gefunden wird, gehen Sie mit dem erhaltenen Pfad zurück zu Schritt 1.

Auf diese Weise sammle ich alle Betriebssystempakete, die für einen Pfad erforderlich sind. Das funktioniert ziemlich gut, aber ich suche nach einem besseren/saubereren Ansatz zur Lösung dieser Aufgabe. Und was halten Sie von meinem vorgeschlagenen Algorithmus?

Ich verwende OpenSUSE, falls das wichtig ist.

Antwort1

$ cat installer.sh
#! /bin/bash

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

Abhängigkeitsbaum

verwandte Informationen