给定一个路径,我想检测需要安装的所有操作系统软件包,以便使用它。例如:
> /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
这意味着需要安装一个必需的操作系统包才能使用/sadd/python/lib/python3.7/lib-dynload/_sqlite3.cpython-37m-x86_64-linux-gnu.so
。
现在,我可以创建一个脚本,该脚本运行上述rpm
命令,然后ldd
在每个路径上运行该命令并迭代该共享库(可能需要使用,locate
因为有时没有路径,例如 for linux-vdso.so.1
)。但:
- 不建议使用
ldd
。 - 输出的解析
ldd
非常难看。
现在,我看到了一个相关的话题就此事。我可以使用readelf
但同样的问题。
是否有更好的解决方案来检测给定路径所需的所有操作系统软件包?我也在使用rpmdep.pl但它期望获取包名称并返回所有包依赖项。所以现在我的算法是:
- 运行
/bin/rpm -qf --queryformat "[%{NAME}]\n" $path
并获取包名称(用 标记$package)
。并将其添加到包列表中。 - 运行
rpmdep.pl $package
) 并将所有包添加到列表中。 ldd $path
对每一行 运行和 :- 如果存在路径(如
libsqlite3.so.0 => /usr/lib64/libsqlite3.so.0
),则使用 回到步骤 1/usr/lib64/libsqlite3.so.0
。 - 如果没有路径(如
linux-vdso.so.1
),则尝试找到它(使用locate
命令),如果找到,则使用您获得的路径返回到步骤 1。
- 如果存在路径(如
这样我就可以收集路径所需的所有操作系统包。它工作得很好,但我正在寻找一种更好/干净的方法来解决这个任务。另外,您认为我建议的算法怎么样?
如果这很重要的话,我正在使用 OpenSUSE。