在 Linux 中管理共享库

CompTIABeginner
立即练习

介绍

在本实验中,你将学习在 Linux 中管理共享库的基础知识。共享库是至关重要的组件,它允许多个程序使用相同的代码,从而节省磁盘空间和内存。你将首先使用 ldd 命令检查一个可执行程序(例如 ping),并识别它正常运行所依赖的具体共享库。

在此基础上,你将学习如何使用 find 命令在文件系统中定位特定库的物理文件。最后,你将探索如何管理共享库缓存,这是关乎系统性能的关键组件。你将使用 ldconfig 工具来查看当前缓存并进行重建,以确保系统能够高效地找到并加载必要的库。

使用 ldd 识别共享库依赖

在这一步中,你将学习如何识别可执行程序所依赖的共享库。在 Linux 中,大多数程序并不包含运行所需的所有代码。相反,它们依赖于共享库,这些库是可以被多个程序同时使用的代码集合。这种方法节省了磁盘空间和内存。ldd(List Dynamic Dependencies,列出动态依赖)命令是一个用于打印每个程序或库所需的共享库的实用工具。

让我们使用 ldd 来检查 ping 命令,这是一个常用的网络工具。这将向我们展示 ping 运行所需的共享库。在终端中运行以下命令:

ldd /bin/ping

你将看到类似以下的输出。具体的内存地址(括号中的数字)和路径在你的系统上可能会略有不同,但库名称应该是相同的。

        linux-vdso.so.1 (0x00007ffcfa17e000)
        libcap.so.2 => /lib/x86_64-linux-gnu/libcap.so.2 (0x00007f29235c4000)
        libidn2.so.0 => /lib/x86_64-linux-gnu/libidn2.so.0 (0x00007f29235a3000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f292337a000)
        libunistring.so.2 => /lib/x86_64-linux-gnu/libunistring.so.2 (0x00007f29231d0000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f29235f5000)

此输出列出了 /bin/ping 所需的共享库。每一行代表一个依赖项。

  • libc.so.6 是标准 C 库,它提供了诸如打开文件、向屏幕写入内容以及管理内存等基本功能。=> 符号表示系统的动态链接器找到该库文件的路径。
  • libcap.so.2 提供了用于处理 Linux 能力(capabilities)的管理功能。
  • libidn2.so.0 提供国际化域名支持。
  • libunistring.so.2 提供 Unicode 字符串处理功能。
  • linux-vdso.so.1 是由内核提供的虚拟库,用于加速某些系统调用。
  • /lib64/ld-linux-x86-64.so.2 是程序解释器本身,负责加载其他共享库。

现在你已经知道如何查看程序的依赖关系,在下一步中,我们将学习如何在文件系统中定位其中一个库的物理文件。

使用 find 定位特定的共享库

在上一步中,你使用 ldd 命令看到 /bin/ping 依赖于 libc.so.6 共享库。现在,你将学习如何在系统文件系统中找到该库文件的确切位置。对于此任务,我们将使用 find 命令,这是一个用于搜索文件和目录的强大工具。

find 命令在目录层级结构中搜索文件。其基本语法是 find [起始目录] -name [文件名]。我们将从 /usr 目录开始搜索,这是许多系统库的常用存放位置。

要定位 libc.so.6 文件,请在终端中执行以下命令。我们使用 sudo 来赋予该命令管理员权限,这可以防止在搜索受系统保护的目录时出现「权限被拒绝」的错误。

sudo find /usr -name libc.so.6

由于我们仅在 /usr 目录中搜索,该命令应该会很快完成。你将看到如下输出:

/usr/lib/x86_64-linux-gnu/libc.so.6

这显示了 C 标准库文件在 /usr 目录中的位置。请注意,这与 ldd 显示的路径(/lib/x86_64-linux-gnu/libc.so.6)不同。这是因为在不同位置可能存在库的多个副本,系统通常使用符号链接来管理实际加载的版本。

如果你想在整个文件系统中搜索库的所有副本,可以使用根目录 / 作为起点:

sudo find / -name libc.so.6

虽然 find 是定位任何文件的通用工具,但 Linux 有一种专门且更快速的机制来管理和定位共享库,即库缓存。在下一步中,你将学习如何查看此缓存。

使用 ldconfig -p 查看共享库缓存

在上一步中,你使用 find 命令在整个文件系统中搜索库,这可能会很慢。为了加快定位共享库的过程,Linux 系统维护一个缓存文件,通常位于 /etc/ld.so.cache。该缓存包含标准系统目录中可用共享库的编译列表,允许程序更快速地加载其依赖项。

ldconfig 命令是管理此缓存的主要工具。要查看当前库缓存的内容,可以使用 -p(打印)选项。

执行以下命令以显示缓存中已知的所有库:

ldconfig -p

输出会非常长,因为典型的系统有很多共享库。该命令会列出找到的库数量,然后打印每一个库。以下是输出内容的一小部分示例:

1234 libs found in cache `/etc/ld.so.cache'
 libzstd.so.1 (libc6,x86-64) => /lib/x86_64-linux-gnu/libzstd.so.1
 libz.so.1 (libc6,x86-64) => /lib/x86_64-linux-gnu/libz.so.1
 libz.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libz.so
 libyield.so.2 (libc6,x86-64) => /lib/x86_64-linux-gnu/libyield.so.2
...
 libc.so.6 (libc6,x86-64) => /lib/x86_64-linux-gnu/libc.so.6
...

每一行显示了库名称、其架构和 ABI(例如 libc6,x86-64),以及库文件的完整路径。

为了避免滚动浏览整个列表,你可以将输出通过管道传输给 grep 来搜索特定的库。让我们找到我们一直在研究的 libc.so.6 的条目:

ldconfig -p | grep libc.so.6

这将过滤列表并仅显示与 libc.so.6 相关的条目:

        libc.so.6 (libc6,x86-64, OS ABI: Linux 3.2.0) => /lib/x86_64-linux-gnu/libc.so.6

如你所见,与搜索整个文件系统相比,这是一种更快、更直接的查找缓存库位置的方法。输出不仅显示了库名称和路径,还显示了架构信息(libc6,x86-64)和操作系统 ABI 兼容性(OS ABI: Linux 3.2.0)。然而,这个缓存并不是实时自动更新的。如果你安装了新库,必须更新缓存以便系统能够找到它。在下一步中,你将学习如何操作。

使用 ldconfig -v 重建共享库缓存

在这一步中,你将学习如何手动更新或重建共享库缓存。这是系统管理员的一项常见任务,尤其是在从源码安装新库或软件包安装未自动触发缓存更新时。最新的缓存对于系统的动态链接器找到新添加的库至关重要。

我们将再次使用 ldconfig 命令,但这次是为了执行更新。当不带 -p 选项运行时,ldconfig 会扫描受信任的目录(定义在 /etc/ld.so.conf/etc/ld.so.conf.d/*.conf 中)以查找共享库,并重建缓存文件 /etc/ld.so.cache

为了观察这个过程,我们将使用 -v(详细)选项,这会使 ldconfig 在扫描目录时打印目录名称以及它创建的符号链接。由于此命令会修改系统文件,你需要使用 sudo 运行它。

在终端中执行以下命令:

sudo ldconfig -v

该命令在处理系统上所有的库目录时会产生大量输出。输出将类似于以下片段:

/lib/x86_64-linux-gnu:
 libip6tc.so.2 -> libip6tc.so.2.0.0
 libip4tc.so.2 -> libip4tc.so.2.0.0
 libxtables.so.12 -> libxtables.so.12.1.0
 ...
/usr/lib/x86_64-linux-gnu:
 libfakeroot-0.so -> libfakeroot-0.so
 ...
/lib:
...
(etc.)

输出首先显示正在扫描的目录路径(例如 /lib/x86_64-linux-gnu:),随后是它在该目录中检查或创建的符号链接。这种详细输出是确认缓存已成功重建并包含所有预期库路径的好方法。

你现在已经完成了在 Linux 中管理共享库的基本任务:识别依赖关系、定位库文件以及管理动态链接器的缓存。

总结

在本实验中,你学习了在 Linux 环境中管理共享库的基本技能。你首先使用 ldd 命令识别了可执行程序的动态依赖关系,揭示了其运行所需的共享库。接着,你练习了使用 find 命令在文件系统中定位特定库的物理文件,这是故障排除和验证的一项实用技能。

此外,你还探索了共享库缓存的作用,系统利用该缓存来加速查找库的过程。你学习了如何使用 ldconfig -p 命令查看此缓存的内容。最后,你使用 ldconfig -v 重建了缓存,这是安装新库后确保它们被系统识别并可用的关键步骤。