在 Linux 中使用 RPM 管理软件包

Red Hat Enterprise LinuxBeginner
立即练习

介绍

在本实验中,你将学习如何在基于 RPM 的 Linux 发行版上,利用强大的 rpm 命令行工具来管理软件。你将亲自动手实践核心的软件包管理任务,包括查询详细的软件包信息、验证已安装软件包的完整性以及检查 RPM 文件的内部内容。

在接下来的步骤中,你将使用特定的 rpm 命令来查找文件所属的软件包、列出软件包的依赖项和配置文件,并检查反向依赖关系。你还将学习如何安全地模拟软件包的卸载以评估其影响,以及如何在安装前使用 rpm2cpiocpio 等工具查看 RPM 软件包文件的内容。

这是一个引导实验,提供分步指导以帮助你学习和练习。请仔细按照说明完成每个步骤并获取实践经验。历史数据表明,这是一个初学者级别的实验,完成率为 95%。它在学习者中获得了 98% 的好评率。

使用 rpm -qirpm -qf 查询基础软件包信息

在这一步中,你将学习如何使用红帽软件包管理器(Red Hat Package Manager,简称 rpm)查询已安装软件包的信息。rpm 是在 CentOS、Fedora 和 RHEL 等基于 RPM 的 Linux 发行版上管理软件的强大命令行工具。我们将重点关注两个基础查询选项:-qi 用于获取详细的软件包信息,-qf 用于查找特定文件所属的软件包。

首先,让我们检查系统中已安装软件包的详细信息。bash 终端(Shell)是系统的核心组件,是一个完美的示例。-q 标志代表「查询」(query),i 标志代表「信息」(information)。

在终端中执行以下命令来查询 bash 软件包的信息:

rpm -qi bash

你将看到列出软件包各种属性的详细输出。输出内容类似于以下内容(版本号和日期可能会有所不同):

Name        : bash
Version     : 4.4.20
Release     : 5.el8
Architecture: x86_64
Install Date: <some_date>
Group       : System Environment/Shells
Size        : 4989189
License     : GPLv3+
Signature   : RSA/SHA256, <some_date_and_time>, Key ID <some_key_id>
Source RPM  : bash-4.4.20-5.el8.src.rpm
Build Date  : <some_date>
Build Host  : <some_build_host>
Relocations : (not relocatable)
Vendor      : CentOS
URL         : http://www.gnu.org/software/bash
Summary     : The GNU Bourne-Again Shell
Description :
The GNU Bourne-Again Shell (Bash) is a shell or command language
interpreter that is compatible with the Bourne shell (sh). Bash
incorporates useful features from the Korn shell (ksh) and the C
shell (csh).  Most sh scripts can be run by bash without
modification.

这段输出提供了丰富的信息,包括软件包的版本、用途摘要以及更详细的描述。

现在,假设你的系统上有一个文件,例如位于 /usr/bin/bashbash 可执行文件,你想知道是哪个软件包安装了它。这在进行系统审计或故障排除时是一项常见的任务。为此,你可以使用 -qf 标志,其中 f 代表「文件」(file)。

运行以下命令来找出哪个软件包拥有 /usr/bin/bash 文件:

rpm -qf /usr/bin/bash

该命令将返回提供此文件的软件包全名:

bash-5.1.8-9.el9.x86_64

如你所见,系统正确识别出 /usr/bin/bash 来自 bash 软件包,这与我们之前发现的信息相吻合。你甚至可以组合这些标志,通过运行 rpm -qif /usr/bin/bash 直接获取拥有该文件的软件包信息。

使用 rpm -qRrpm -qc 列出软件包依赖项和配置文件

在这一步中,你将继续探索 rpm,学习如何列出软件包的依赖关系及其关联的配置文件。了解依赖关系至关重要,因为大多数软件都依赖其他软件包才能正常运行。而了解配置文件的位置对于系统管理和自定义设置也是必不可少的。

让我们先来看看 bash 软件包需要哪些其他软件包或功能。我们使用 -qR(或 --requires)标志来实现这一点。R 代表「需求」(requires)。

执行以下命令查看 bash 的依赖项:

rpm -qR bash

输出将是 bash 所依赖的软件包和系统功能的列表。这个列表可能会很长。

/bin/sh
config(bash) = 4.4.20-5.el8
filesystem >= 3
glibc
info
libc.so.6(GLIBC_2.17)(64bit)
libc.so.6(GLIBC_2.2.5)(64bit)
libc.so.6(GLIBC_2.28)(64bit)
libc.so.6(GLIBC_2.3)(64bit)
...
rtld(GNU_HASH)

此输出显示 bash 需要 glibc 软件包(提供 C 语言库 libc.so.6)、filesystem 软件包以及其他系统级组件。

接下来,让我们查找作为 bash 软件包一部分安装的配置文件。当你需要为新用户修改终端的默认行为时,这非常有用。为此使用 -qc 标志,其中 c 代表「配置文件」(configfiles)。

运行此命令列出 bash 的配置文件:

rpm -qc bash

输出将显示配置文件的完整路径:

/etc/skel/.bash_logout
/etc/skel/.bash_profile
/etc/skel/.bashrc

/etc/skel 中的这些文件是模板文件,当创建新用户账户时,它们会被复制到新用户的家目录中。

你还可以组合标志来查找与特定命令相关的配置文件。例如,要查看 passwd 命令使用的配置文件,可以使用 -qcf。这告诉 rpm 先找到该文件所属的软件包(-f /usr/bin/passwd),然后列出其配置文件(-c)。

rpm -qcf /usr/bin/passwd

该命令揭示了与 passwd 工具关联的配置文件:

/etc/pam.d/passwd

这是一种快速识别更改命令行为所需编辑的文件的强大方法。

使用 rpm -V 验证软件包完整性和文件更改

在这一步中,你将学习如何使用 rpm -V(或 rpm --verify)验证已安装软件包的完整性。此命令是至关重要的安全和故障排除工具。它会将软件包安装的文件与 RPM 数据库中存储的信息(如文件大小、权限和校验和)进行比对。这使你能够检测到对系统文件进行的任何未经授权或意外的更改。

首先,让我们确保系统上安装了几个实用工具包:lsscsiat。我们将使用它们进行验证测试。

sudo dnf install -y lsscsi at

现在,让我们验证 lsscsi 软件包。由于我们刚刚安装它且未做任何更改,它应该能通过验证测试。成功的验证不会产生任何输出。

rpm -V lsscsi

正如预期的那样,命令提示符直接返回,没有任何消息,这表明 lsscsi 软件包中的所有文件都处于原始状态。

接下来,让我们故意修改一个配置文件,看看 rpm -V 如何报告更改。我们将向 /etc/at.deny 文件添加一行,该文件属于 at 软件包。此文件控制哪些用户不被允许使用 at 命令。

echo "labex" | sudo tee -a /etc/at.deny

既然我们已经修改了一个文件,让我们再次验证 at 软件包。

sudo rpm -V at

这一次,命令产生了输出,表明检测到了更改:

S.5....T.  c /etc/at.deny

让我们分析一下这个输出:

  • S:文件大小(Size)已更改。
  • 5:MD5 校验和已更改。
  • T:修改时间(Time)已更改。
  • c:这表示是一个配置文件(configuration file)。
  • /etc/at.deny:被修改文件的路径。

8 位字符串 S.5....T. 中的每个字符位置代表不同的测试。. 表示该项测试通过。此输出清楚地显示 /etc/at.deny 配置文件自安装以来已被改动。

你还可以使用 -qVf 标志直接验证拥有特定文件的软件包。

sudo rpm -qVf /etc/at.deny

该命令将产生相同的输出,因为它首先找到拥有 /etc/at.deny 的软件包(即 at),然后对其进行验证。

检查反向依赖并使用 rpm -e --test 模拟软件包卸载

在这一步中,你将学习如何检查反向依赖关系并安全地模拟软件包的卸载。虽然 rpm -qR 命令显示软件包「需要」什么(其依赖项),但 rpm -q --whatrequires 显示哪些其他软件包「需要它」(其反向依赖项)。在卸载软件包之前了解这一点极其重要,因为你可能会破坏系统的其他部分。

为了安全地检查卸载软件包的后果,你可以使用 rpm -e --test 命令。-e 标志代表「擦除」(erase),而 --test 标志告诉 RPM 进行模拟运行,而不实际删除任何文件。

让我们先检查一个许多其他软件包都依赖的核心系统软件包。glibc 软件包提供了 GNU C 库,它是 Linux 系统上几乎所有程序的基础。让我们看看哪些软件包需要 glibc

rpm -q --whatrequires glibc

输出将显示多个依赖于 glibc 的软件包:

glibc-common-2.34-168.el9_6.19.x86_64
glibc-langpack-en-2.34-168.el9_6.19.x86_64
libstdc++-11.5.0-5.el9_5.x86_64
glibc-headers-2.34-168.el9_6.19.x86_64
pam-1.5.1-23.el9.x86_64
glibc-devel-2.34-168.el9_6.19.x86_64
nscd-2.34-168.el9_6.19.x86_64

如你所见,许多关键的系统软件包都依赖于 glibc。现在让我们看看尝试卸载 glibc 时会发生什么。我们将使用 --test 标志以确保不会真的卸载它,否则会破坏整个系统。

sudo rpm -e --test glibc

由于非常多的软件包需要 glibc,RPM 将报告依赖错误并阻止卸载。输出将显示一长串失败的依赖项:

error: Failed dependencies:
 glibc = 2.34-168.el9_6.19 is needed by (installed) glibc-common-2.34-168.el9_6.19.x86_64
 glibc = 2.34-168.el9_6.19 is needed by (installed) glibc-langpack-en-2.34-168.el9_6.19.x86_64
 glibc >= 2.34 is needed by (installed) libstdc++-11.5.0-5.el9_5.x86_64
 ... (additional dependency errors)

现在让我们看一个依赖项较少的软件包。我们之前安装的 lsscsi 软件包是一个实用工具包,其反向依赖项较少。让我们检查谁需要它:

rpm -q --whatrequires lsscsi

你应该会看到表示没有软件包需要 lsscsi 的输出:

no package requires lsscsi

既然没有软件包依赖于 lsscsi,我们可以安全地模拟它的卸载:

sudo rpm -e --test lsscsi

该命令应该在没有错误的情况下完成,这表明卸载 lsscsi 不会破坏系统上的任何其他软件包。

这演示了你如何通过先检查反向依赖关系来预测卸载软件包的影响,从而避免破坏系统。

使用 rpm2cpiocpio 检查 RPM 软件包内容

在这一步中,你将学习一种强大的技术,可以在「不安装」的情况下检查 RPM 软件包文件的内容。这对于在安装前验证软件包包含的文件,或者从软件包中提取单个文件以恢复损坏或删除的文件非常有用。这个过程涉及两个命令:rpm2cpio 将 RPM 文件转换为 cpio 归档文件,而 cpio 则可以列出或从该归档中提取文件。

首先,你需要一个实际的 .rpm 文件来进行检查。让我们使用 dnf 软件包管理器将 bash 的软件包文件下载到当前目录(~/project)。download 子命令会获取软件包文件而不进行安装。

sudo dnf download bash

你将看到表示文件已成功下载的输出。文件名将包含版本和架构信息。

Last metadata expiration check: ...
bash-<version>.<arch>.rpm

现在,使用 ls 命令确认 .rpm 文件已在你的 ~/project 目录中:

ls bash-*.rpm

准备好 RPM 文件后,你现在可以同时使用 rpm2cpiocpio 命令来列出其内容。rpm2cpio 命令读取 RPM 文件并将 cpio 归档输出到标准输出。然后我们通过管道(|)将此输出传递给 cpio 命令,后者从其标准输入读取归档。cpio-t 标志告诉它列出内容列表。

rpm2cpio bash-*.rpm | cpio -t

这将产生 bash 软件包中包含的所有文件和目录的长列表。输出看起来像这样:

.
./etc
./etc/skel
./etc/skel/.bash_logout
./etc/skel/.bash_profile
./etc/skel/.bashrc
./usr
./usr/bin
./usr/bin/bash
./usr/bin/sh
./usr/share
./usr/share/doc
...

这种技术让你能够完整地查看软件包的负载,从而确切地看到如果安装该软件包,哪些文件将被放置到你的系统中。

总结

在本实验中,你学习了如何在 Linux 环境中使用 RPM 工具管理和查询软件包。你首先通过 rpm -qi 获取了已安装软件包的详细信息,并使用 rpm -qf 识别了特定文件所属的软件包。你还练习了使用 rpm -qR 列出软件包的依赖项,以及使用 rpm -qc 查找其配置文件,从而全面了解了软件包如何集成到系统中。

在这些查询技能的基础上,你学习了使用 rpm -V 验证已安装软件包文件的完整性以检查是否有改动。你还探索了如何安全地检查反向依赖关系,并使用 rpm -e --test 模拟软件包卸载,以便在不做出实际更改的情况下了解潜在影响。最后,你掌握了在安装前通过 rpm2cpiocpio 提取并列出 RPM 软件包文件内容的能力。