在 Linux 中使用 RPM 管理软件包

红帽企业 LinuxBeginner
立即练习

介绍

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

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

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

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

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

首先切换到实验工作目录,以便将本实验中创建的命令输出文件统一存放:

cd /home/labex/project

在终端中执行以下命令,查询 bash 软件包的信息并将输出保存到 bash-package-info.txt

rpm -qi bash | tee bash-package-info.txt

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

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 文件所属的软件包,并将结果保存到 bash-owner.txt

rpm -qf /usr/bin/bash | tee bash-owner.txt

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

bash-5.1.8-9.el9.x86_64

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

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

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

继续在 /home/labex/project 目录下工作。首先,让我们找出 bash 软件包还需要哪些其他软件包或功能。我们为此使用 -qR(或 --requires)标志。R 代表“需求”(requires)。

执行以下命令查看 bash 的依赖项并将输出保存到 bash-requires.txt

rpm -qR bash | tee bash-requires.txt

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

/bin/sh
config(bash) = 4.4.20-5.el8
filesystem >= 3
libc.so.6()(64bit)
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 依赖于核心系统功能,如 libc.so.6filesystem 软件包以及其他运行时组件。

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

运行此命令列出 bash 的配置文件并将输出保存到 bash-config-files.txt

rpm -qc bash | tee bash-config-files.txt

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

/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 | tee passwd-config-files.txt

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

/etc/pam.d/passwd

这是一种快速识别你可能需要编辑哪些文件来更改命令行为的强大方法。

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

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

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

sudo dnf install -y lsscsi at

继续在 /home/labex/project 目录下工作。现在,让我们验证 lsscsi 软件包。由于我们刚刚安装了它且没有进行任何更改,它应该能通过验证测试。验证成功时不会产生任何输出。

rpm -V lsscsi | tee lsscsi-verify.txt

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

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

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

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

sudo rpm -V at | tee at-verify.txt

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

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 | tee at-file-verify.txt

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

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

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

继续在 /home/labex/project 目录下工作。要安全地检查卸载软件包的后果,可以使用 rpm -e --test 命令。-e 标志代表“擦除”(erase),--test 标志告诉 RPM 执行一次试运行,而不会真正删除任何文件。

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

rpm -q --whatrequires glibc | tee glibc-whatrequires.txt

输出将显示几个依赖于 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 2>&1 | tee glibc-remove-test.txt

由于许多软件包都需要 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 | tee lsscsi-whatrequires.txt

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

no package requires lsscsi

由于没有软件包依赖于 lsscsi,我们可以安全地模拟其卸载:

sudo rpm -e --test lsscsi 2>&1 | tee lsscsi-remove-test.txt

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

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

使用 rpm2cpiocpio 查看 RPM 软件包内容

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

继续在 /home/labex/project 目录下工作。首先,你需要一个实际的 .rpm 文件来查看。让我们使用 dnf 软件包管理器将 bash 的软件包文件下载到当前目录(/home/labex/project)。download 子命令可以在不安装的情况下获取软件包文件。

sudo dnf download bash

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

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

现在,使用 ls 命令确认 .rpm 文件位于你的 /home/labex/project 目录中:

ls bash-*.rpm

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

rpm2cpio bash-*.rpm | cpio -t | tee bash-rpm-contents.txt

这将生成 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 软件包文件内容的能力。