RPM 包是什么?

在基于 Red Hat 的 Linux 发行版(如 CentOS、Fedora、RHEL)中,软件通常以一种特定的包格式分发,这种格式就是 RPM (Red Hat Package Manager)。一个 `.rpm` 文件本质上是一个包含软件程序本身、安装脚本、配置文件、文档等所有必需文件的归档文件,并且包含了该软件包的元数据,比如它的名称、版本、发行号、依赖关系、描述信息等。

RPM 包系统的设计目的是为了简化软件的安装、升级、卸载和管理过程。它提供了一种标准化的方法来打包软件,并提供工具来处理这些包。

为什么使用 RPM 包安装?

直接使用 `.rpm` 文件配合 `rpm` 命令进行安装,相比于从源代码编译安装有以下几个主要优点:

  • 标准化和方便: 软件包是预编译好的,只需简单的命令即可安装,无需处理编译环境和过程。
  • 文件完整性校验: RPM 包包含校验和,安装工具可以验证文件的完整性,确保包在下载或传输过程中没有损坏或被篡改。
  • 文件跟踪: RPM 数据库会记录每个已安装软件包包含哪些文件以及它们安装到哪里,这使得升级和卸载更加干净彻底。
  • 依赖关系信息: RPM 包元数据中包含了它运行所需的其他软件包信息。虽然 `rpm` 命令本身不自动解决依赖,但它会检查并提示缺少的依赖项。

需要注意的是,通常情况下,更推荐使用高层的包管理器(如 `yum` 或 `dnf`)来安装软件,因为它们能够自动处理依赖关系并从配置好的软件仓库中下载软件包。直接使用 `rpm` 命令更适合安装本地下载的单个或少量不涉及复杂依赖的 RPM 文件,或者进行一些特殊的安装/升级操作。

如何安装 RPM 包?

安装 RPM 包主要使用 `rpm` 命令。最基本的安装命令如下:

rpm -i package_name.rpm

这里的 package_name.rpm 是你要安装的 RPM 文件名。

常用的安装选项

在安装过程中,你可能会用到一些常用的选项来获取更多信息或控制安装行为:

  • -i--install:安装软件包。
  • -v:显示详细信息(verbose)。会在安装过程中输出更多执行细节。
  • -h--hash:显示进度哈希符号(#)。安装时会打印 # 符号表示进度,每完成一部分会打印一个 #,通常和 -v 一起使用。
  • -U--upgrade:升级软件包。如果软件包已安装,则执行升级;如果未安装,则执行安装。这是比 -i 更常用的安装方式,因为它能处理新旧版本的替换。
  • -F--freshen:刷新软件包。只在软件包已安装的情况下执行升级;如果未安装,则不做任何操作。

通常,安装或升级时会组合使用 -ivh-Uvh 选项:

rpm -ivh package_name.rpm

rpm -Uvh package_name.rpm

这些命令会以可视化进度(h)和详细模式(v)安装(i)或升级(U)指定的 RPM 文件。

处理依赖关系

RPM 包通常依赖于其他特定的软件包或库才能正常运行。当你使用 rpm -i 命令安装一个有依赖的包时,如果依赖项没有被满足,安装将会失败并报错,提示缺少的依赖包名称和版本要求。

error: Failed dependencies:
    required_package >= version is needed by package_name-version-release.architecture

使用 `rpm` 命令直接安装的最大痛点在于它不会自动查找和安装这些依赖项。你需要手动找到并先安装所有依赖的 RPM 包,这可能形成一个复杂的“依赖链”,非常繁琐。

如何处理依赖?

  1. 手动解决(不推荐用于复杂依赖): 根据错误提示,手动下载并安装所有缺少的依赖包。如果依赖包本身还有依赖,则需要重复此过程。
  2. 使用高级包管理器(强烈推荐): 将 RPM 包放在一个本地仓库中,或者如果软件包在配置好的在线仓库中,使用 yum localinstall package_name.rpm (在旧系统上) 或 dnf install package_name.rpm (在新系统上)。这些命令会自动解析并安装所有必需的依赖项。
  3. 忽略依赖(极不推荐): 使用 --nodeps 选项强制安装,忽略依赖检查:

    rpm -ivh --nodeps package_name.rpm

    警告: 使用 --nodeps 安装的软件包很可能因为缺少依赖而无法正常运行,甚至可能破坏系统上已有的软件功能。除非你非常清楚自己在做什么,否则永远不要使用这个选项。

安装多个 RPM 包

如果你有多个 RPM 包需要安装,可以在命令中列出它们的文件名:

rpm -ivh package1.rpm package2.rpm package3.rpm

或者使用通配符(但要注意顺序和依赖):

rpm -ivh *.rpm

同样,使用 yum install *.rpmdnf install *.rpm 通常是更好的选择,因为它们会处理多个包之间的依赖关系。

强制安装或升级

在某些特殊情况下,你可能需要强制安装或升级,例如要覆盖已有的文件,或者安装一个与现有包冲突的版本(通常不建议这样做)。可以使用 --force 选项:

rpm -ivh --force package_name.rpm

rpm -Uvh --force package_name.rpm

--force 选项实际上是以下几个选项的组合:

  • --replacepkgs:重新安装已安装的包。
  • --replacefiles:安装新包时替换掉系统中与包内文件同名的其他文件,即使这些文件不属于任何已知的 RPM 包。
  • --oldpackage:允许安装一个比当前已安装版本更旧的包(降级)。

警告: 使用 --force 是非常危险的操作!它可能会破坏系统稳定性,覆盖重要的配置文件而导致服务无法启动,或者引起软件包数据库的混乱。务必谨慎使用,并确保你知道其潜在后果。

如何卸载 RPM 包?

卸载 RPM 包使用 rpm -e 命令。需要提供的是软件包的名称,而不是 RPM 文件名。

首先,你需要知道软件包的准确名称。可以使用 rpm -qa 命令列出所有已安装的软件包:

rpm -qa | grep package_part_name

找到完整的软件包名称后,执行卸载命令:

rpm -e package_name

例如,要卸载名为 firefox 的软件包:

rpm -e firefox

卸载时的依赖关系

如果其他已安装的软件包依赖于你尝试卸载的包,rpm -e 命令会阻止卸载并报错:

error: Failed dependencies:
    package_name is needed by required_package-version-release.architecture

这意味着你需要先卸载依赖于它的其他包,或者同时卸载它们(如果它们之间没有其他复杂的相互依赖)。

忽略依赖进行卸载(极不推荐): 同样,你可以使用 --nodeps 选项强制卸载:

rpm -e --nodeps package_name

警告: 强制卸载被其他包依赖的软件包会导致依赖它的软件无法正常工作,甚至可能导致系统不稳定。除非你非常清楚自己在做什么,否则避免使用此选项。

哪里可以获取 RPM 包?

获取 RPM 包的主要途径有:

  1. 官方软件仓库: 这是最推荐的方式。配置在系统中的软件仓库(repositories)包含了大量经过测试和验证的软件包。使用高级包管理器(yumdnf)从这些仓库安装软件时,它们会自动下载对应的 RPM 文件并处理依赖。
  2. 项目官方网站: 一些软件项目会在其官方网站上提供针对特定 Linux 发行版和架构的 RPM 包下载。例如,Google Chrome、Microsoft Edge、VS Code 等。
  3. 第三方仓库: 有些社区或组织会维护自己的软件仓库,提供官方仓库中没有的软件或更新的版本。添加第三方仓库需要谨慎,要确保其来源可靠。
  4. 本地构建: 对于开发者或需要特殊配置的用户,可以从源代码构建软件并生成 RPM 包。

从官方仓库或信誉良好的第三方仓库获取并使用 yumdnf 安装是最安全和便捷的方式。直接下载和安装单个 RPM 文件时,请确保文件来源可靠,以避免安装恶意软件或损坏的包。

RPM 包安装的文件会放在哪里?

RPM 包安装的文件会分散到文件系统的不同目录中,遵循 Linux 文件系统的标准结构 (Filesystem Hierarchy Standard, FHS)。具体位置取决于软件包的类型和文件用途。常见的文件安装路径包括:

  • /usr/bin//usr/sbin/:可执行程序。
  • /usr/lib//usr/lib64/:库文件。
  • /etc/:配置文件。
  • /var/:变量数据文件,如日志文件、缓存文件等。
  • /usr/share/doc/:文档文件。
  • /usr/share/man/:手册页。

当你使用 rpm -ql package_name 命令时,可以列出指定已安装软件包安装的所有文件及其对应的路径。

rpm -ql firefox

这个命令会显示 Firefox 软件包安装了哪些文件以及它们位于文件系统中的具体位置。

如何验证已安装的 RPM 包?

安装完成后,你可以使用 rpm -V 命令来验证已安装软件包的文件完整性和属性。这个命令会比较当前系统上的文件与 RPM 数据库中记录的该软件包安装时应有的状态。

rpm -V package_name

如果文件发生了变化(例如权限、所有者、大小、校验和等),或者文件丢失,rpm -V 会输出一行信息,用一系列字符来指示哪些属性不匹配。如果没有输出,表示软件包的文件是完整的,且属性与安装时一致。

输出中的字符含义(出现在属性前):

  • S:File size differs (文件大小不同).
  • M:Mode differs (permissions, sticky bit) (文件权限或特殊位不同).
  • 5:MD5 checksum differs (MD5 校验和不同).
  • D:Device major/minor number mismatch (设备号不同).
  • L:readLink(2) path mismatch (软链接指向路径不同).
  • U:User ownership differs (用户所有者不同).
  • G:Group ownership differs (组所有者不同).
  • T:mTime differs (修改时间不同).
  • P:Capabilities differ (Capabilities 不同).

例如,输出 .M....... /etc/myprogram.conf 表示 /etc/myprogram.conf 这个文件的权限发生了变化。

验证功能对于排查问题(例如软件行为异常、文件被意外修改或删除)非常有用。

如何列出所有已安装的 RPM 包?

使用 rpm -qa 命令可以列出系统上所有通过 RPM 方式安装的软件包及其完整名称:

rpm -qa

这个列表可能会非常长。通常你会结合 grep 命令来查找特定的软件包:

rpm -qa | grep httpd

上面的命令会查找所有名称中包含 “httpd” 的已安装软件包,比如 httpd-2.4.6-97.el7.centos.x86_64

总结

rpm 命令是 Linux 系统中用于管理 `.rpm` 软件包的底层工具。它可以用于安装、升级、卸载、验证和查询软件包。然而,它最主要的限制在于不具备自动解决软件包依赖的能力。

因此,在大多数情况下,尤其是安装涉及多个依赖的软件时,强烈推荐使用基于 rpm 的高级包管理器,如 yum (在较旧的系统上) 或 dnf (在较新的系统上)。这些工具通过访问配置好的软件仓库,能够自动查找和安装所有必需的依赖项,使软件管理变得更加简单和可靠。

直接使用 rpm 命令更适合处理本地的单个 RPM 文件,或者进行一些需要绕过依赖检查(如 --nodeps)或强制操作(如 --force)的特殊维护任务,但这些特殊操作应该非常谨慎,并在充分了解风险的情况下进行。


rpm包安装