RPM(Red Hat Package Manager,递归缩写)是 Red Hat 公司开发的一套软件包管理技术体系,包含三个层面:

  1. 一种文件格式 : .rpm 包(把程序 + 元数据 + 安装脚本打包)

  2. 一组管理工具 : rpm 命令行程序

  3. 一个软件数据库 : 记录系统上所有已安装软件的完整信息

它诞生于 1997 年(RPM 1.0,基于 RPP 改进),目前是 Linux 世界事实上的两大包管理阵营之一 :

CentOS/RHEL 系底层包格式 : RPM , 分三层工具:

  1. rpm : 底层工具 , 操作本地 rpm 包 , 不自动解决依赖

  2. yum : CentOS7 默认高层包管理器 , 基于 rpm , 自动处理依赖 , 拉取仓库源

  3. dnf(Dandified YUM) : CentOS8+/RHEL8+ 默认 , yum 升级版 ; CentOS8 里yum只是 dnf 的软链接 , 命令几乎完全兼容

1. RPM 基础原理

rpm命令是RPM软件包的管理工具。rpm原本是Red Hat Linux发行版专门用来管理Linux各项套件的程序 , 由于它遵循GPL规则且功能强大方便 , 因而广受欢迎。逐渐受到其他发行版的采用。RPM套件管理方式的出现 , 让Linux易于安装 , 升级 , 间接提升了Linux的适用度。

2. RPM包基础

2.1 RPM包命令规则

2.1.1 基础命名规则

rpm包的命令规则方式如下图所示

rpm命名规则
  • 软件包名称 : 软件本身名称, 单词标识软件。

  • 版本号 : 软件作者官方的版本号

  • 发布编号(VERSION) : 打包这的打包修订号。软件源码版本没变, 知识修改了打包脚本、补丁, 这个数字会增加。

  • 发行版标识: el7 , 其中el = Enterprise Linux。

    • el7 -> CentOS7/RHEL7

    • el8 -> CentOS8/RHEL8

    • el9 -> Rocky9/RHEL9

  • 架构 : x86_64 ,编译适配的CPU架构

    架构

    说明

    x86_64

    64 位 x86 服务器(绝大多数CentOS 服务器)

    i386 / i686

    老式 32 位 x86 , 现在基本淘汰

    noarch

    无架构 , 和 CPU 无关。一般是脚本、配置包、文档包 , 任何架构都可以安装

    aarch64

    ARM64 架构(鲲鹏、树莓派、arm 服务器)

  • 扩展名 : .rpm , RPM二进制包标识

    源码包后缀 : .src.rpm , 例如 nginx-1.20.1-1.el7.src.rpm , 存放源代码 , 不是直接安装的二进制程序。而是通过源码包手动编译成新的rpm包。或者通过源码包获取对应的源码或者rpmbuild的编译文件

2.1.2 子包命名

很多大型软件 , 不会只打包成单个 rpm 文件 , 而是拆分成多个 RPM 子包。

RPM 打包规范支持将同一个软件项目 , 拆分成多个独立 rpm 包 , 称为子包。 打包时共用一套源码 , 版本号保持一致 , 但是拆分成多个 rpm 文件 ,每个子包只包含一部分文件。

拆包目的

  1. 按需安装 : 只安装需要的组件 , 最小化服务器安装体积(生产最小化部署很重要)

  2. 文件复用 : 公共配置、共享库抽离 , 多个组件共用一份文件 , 避免重复存放

  3. 依赖隔离 : 不同组件依赖不同软件 , 拆包减少不必要依赖

  4. 粒度可控 : 升级时可以单独升级某个子包(同版本下一般一起升级)

命名通用格式 : 软件名-子包标识-版本-发布号-架构.rpm

子包名称

包名后缀

包含内容

使用场景

是否生产运行必需

主包

无后缀 Application-VERSION-ARCH.rpm

软件核心二进制程序、默认基础配置、基础 man 手册

运行软件主体程序

✅ 运行服务一般需要

开发子包

-devel

C/C++ 头文件.h、动态库软链接、pkgconfig 文件

源码编译第三方程序 , 调用该软件 API ; 模块编译

❌ 单纯运行软件不需要

共享库子包

-libs

动态共享库 .so

程序运行依赖 ; 其他软件也可调用这套共享库

✅ 大部分主包会依赖 libs

工具子包

-utils

配套辅助命令、管理脚本、导入导出工具

使用软件配套管理工具

⭕ 按需安装

公共文件子包

-common

共用配置文件、模板、静态资源 , 无可执行程序

server、client 多个组件共用一套配置

✅ 多组件架构软件常用

服务端子包

-server

后台守护进程、服务端程序

部署服务端 ( 数据库、web 服务 )

⭕ 部署服务才安装

客户端子包

-client

客户端命令程序 , 用于连接远程服务

只需要客户端 , 不部署服务端

⭕ 按需安装

静态库子包

-static

静态库文件 .a

静态编译程序 , 将库打包进二进制

❌ 运维极少使用 , C 开发专用

文档子包

-doc

HTML 文档、readme、license、示例说明

本地查阅官方文档

❌ 生产服务器一般不安装

插件子包

-plugins / -plugin

软件扩展插件、功能模块

需要扩展软件功能时安装

⭕ 按需

示例包

-examples

样例配置、模板脚本

学习参考配置

❌ 生产环境不装

测试包

-test

软件自带测试程序、测试用例

软件开发者测试

❌ 生产绝对不装

命令补全包

-bash-completion

bash 自动补全脚本

优化命令行体验

❌ 可选优化

语言绑定包

-python3/-perl/-ruby

对应编程语言 SDK、库绑定

使用对应语言开发调用该软件

⭕ 开发脚本按需安装

示例:

mariadb-5.5.68-1.el7.x86_64.rpm          #主基础包
mariadb-server-5.5.68-1.el7.x86_64.rpm   #服务端子包
mariadb-client-5.5.68-1.el7.x86_64.rpm   #客户端子包
mariadb-libs-5.5.68-1.el7.x86_64.rpm     #共享库子包
mariadb-devel-5.5.68-1.el7.x86_64.rpm    #开发子包
mariadb-doc-5.5.68-1.el7.x86_64.rpm      #文档子包
​

2.2 RPM包依赖

2.2.1 依赖基础

Linux 软件运行或编译时 , 需要调用其他文件、库、程序。RPM 包在打包时 , 会把这些需求写入包内 , 就是依赖(Requires)。 同时 , 包也可以对外提供能力 , 叫做提供(Provides)。

RPM 数据库 /var/lib/rpm 记录本机所有包的 Requires 和 Provides。 rpm 底层工具只会检查依赖 , 不会自动下载安装缺失依赖; yum/dnf 上层工具自动解析、安装依赖。

  • Requires(需要) : 当前包安装 / 运行 , 必须要有哪些东西。

  • Provides(提供) : 当前包可以提供哪些文件、库、虚拟包 , 供别的包依赖。

RPM 依赖的 4 种类型

  • 文件依赖

    依赖某个具体文件路径。 例: /usr/bin/bash , 安装包要求系统必须存在这个文件。

  • 库依赖

    依赖动态共享库 .so。程序运行时加载。 示例 : libc.so.6(glibc 系统基础库 , 几乎所有程序都依赖)

    使用命令 ldd 二进制程序 查看程序运行依赖的动态库。

    它依赖的其实是一个文件 , 而不是软件包。该文件藏身在某一个软件包当中。我们只要将该文件所在的软件包安装上 , 该文件也就安装了。

    解决方法 : 登录www.rpmfind.net网站 , 输入库文件名称查询到对应的rpm包 , 然后安装即可。

  • 软件包依赖

    依赖另外一个 RPM 包(包名 , 可带版本条件) 版本条件符号 : > 大于、>= 大于等于 、< 小于 、<= 小于等于 、= 等于。

    示例 : nginx requires openssl >= 1.0.2 安装 nginx , 系统 openssl 版本必须大于等于 1.0.2。

  • 虚拟包依赖

    不是真实包名 , 打包时自定义虚拟名称 , 多个包可以Provides同一个虚拟包。

    好处 : 多个软件包提供相同能力 , 依赖只写虚拟名字 , 不绑定单一包。

    举例 : httpd 和 nginx 都可以提供 webserver 虚拟包。某个软件依赖 webserver , 安装 httpd 或者 nginx 任意一个都满足依赖。

2.2.2 依赖查询

两类查询 : 1. 已安装包 ; 2. 未安装的 rpm 文件(加 -p)

  1. 查询包的依赖 Requires

    # 查询本机已安装nginx的依赖
    rpm -qR nginx
    ​
    # 查询【尚未安装】的rpm包文件的依赖 ( 加p ) 
    rpm -qpR nginx-1.20.1-1.el7.x86_64.rpm
  2. 查询包对外提供 Provides

    # 查询已安装nginx提供哪些能力
    rpm -q --provides nginx
    ​
    # 查询未安装rpm包的provides
    rpm -qp --provides nginx-1.20.1-1.el7.x86_64.rpm
    ​
  3. 查询哪个包提供某个文件(反向查询)

    # 本机已有文件 , 查归属包 ( 读取本地rpm数据库 ) 
    rpm -qf /usr/bin/ls
    ​
    # 联网查询哪个包能提供该文件 ( yum , 本机不存在文件也能查 ) 
    yum provides */semanage

2.2.3 依赖冲突

同一个系统中 , 两个包不能同时安装 , 称为冲突 Conflicts。 打包时定义 : A 包 Conflicts B 包。安装 A 的时候 , 如果系统已有 B , 直接报错。

场景举例: mysql-community-server 和 mariadb-server 互相冲突 , 不能同时安装。

查看包冲突命令:

rpm -q --conflicts mariadb-server
rpm -qp --conflicts mariadb-server.rpm

2.2.4 依赖处理机制

  1. rpm -ivh : 安装前检查所有 Requires , 依赖缺失直接终止安装 , 不会自动下载。

  2. rpm -e : 卸载前检查 , 如果别的包依赖当前包 , 卸载直接报错。

  3. --nodeps 参数 : 跳过依赖检查 , 强制安装 / 卸载

rpm -ivh --nodeps xxx.rpm
rpm -e --nodeps xxx

依赖本身的形式分为以下两种:

  • 树形依赖 : a->b->c 解决方法 : 从后往前安装

  • 环形依赖 : a->b->c->a 解决方法 : 放在一条命令中安装即可

3. RPM数据库

RPM 数据库是 rpm 包管理器本地的数据库 , 当我们安装 rpm 包的时候 , rpm 会把包的元数据写入这个数据库 ; 查询、校验、卸载软件时 , rpm 读取这个数据库。

注意 : 不是存放软件本身的程序文件 !软件二进制、配置文件仍然安装在 /usr/bin、/etc 等系统目录 ; RPM 数据库只记录软件包的元信息。

路径 : /var/lib/rpm/ 。/var/lib/ 目录的含义 : 可变数据 ,应用程序运行产生的持久化数据。

进入 /var/lib/rpm , 里面是多个Berkeley DB(BDB)数据库文件(CentOS7) , 每个文件是独立的索引表 , 不同表保存不同信息。

文件名称

存储内容

Packages

核心主表 , 最重要! 保存所有已安装包基本信息 : 包名、版本、发布号、架构、摘要、所属用户组等。所有 rpm 查询都优先读这个表

Files

保存每个 rpm 包安装生成的所有文件、路径、文件权限、MD5 值、文件类型 ( 配置文件 / 文档 )

Depends

保存包依赖关系 : Requires ( 依赖 ) 、Provides ( 提供 ) 、Conflicts ( 冲突 )

Name

包名索引 , 根据软件名快速定位 Packages 记录 , 加速 rpm -q 包名 查询

Group

软件组分类索引

Dirnames

目录索引 , 记录包安装产生的目录

Basenames

文件名称索引 , 加速 rpm -qf 根据文件反查所属包

Providename

Provides 索引 , 哪些包提供某个库 / 虚拟包

Requirename

Requires 索引 , 依赖反向索引

Triggername

trigger 触发器相关索引 ( rpm 触发器 )

在上面表格中Packages为主数据表。其余所有 .db 文件都是索引 , 用来加速各类 rpm 查询命令。需要注意 CentOS8+的rpm 数据库后端换成 sqlite , 不再是 Berkeley DB , 文件结构不一样。

当安装一个 rpm 包 , rpm 写入数据库的信息 :

  1. 软件包基础信息 : 包名、version、release、arch、打包时间、厂商、许可证、描述

  2. 文件清单 : 该包安装的所有文件、目录、软链接;每个文件的权限、属主、属组、大小、MD5 校验码;标记哪些是配置文件、哪些是文档

  3. 依赖信息 : Requires(该包依赖的库 / 文件 / 包) ; Provides(该包对外提供的库 / 虚拟包) ; Conflicts(冲突包)

  4. 变更记录 : 安装时间

因此当使用rpm命令查询包相关信息(执行 rpm -ql nginx)的时候, rpm 不是去扫描磁盘 , 而是读取数据库里记录的文件列表。

rpm -V nginx : 读取数据库保存的文件属性、MD5 , 和磁盘上真实文件对比,判断是否改动。

rpm -qf /usr/bin/nginx : 查询 Basenames 索引 ,找到该文件归属的包。

另外RPM 数据库同一时间只允许一个 rpm 事务操作。 当执行 rpm 安装、升级、卸载时,会加锁 ; 此时如果再开一个窗口执行 rpm/yum, 会报错。

RPM数据库有一个常见的故障问题。当数据库因为断电宕机、磁盘满、并发操作等原因导致 数据库损坏时, 会出现以下内容报错信息:

error: db5 error(11) from dbenv->open: Resource temporarily unavailable
error: cannot open Packages index using db5 - Resource temporarily unavailable (11)
error: cannot open Packages database in /var/lib/rpm

如果需要修复, 需要提前备份对应的目录文件: cp -r /var/lib/rpm /var/lib/rpm.bak

  1. 如果因为并发操作导致锁文件残留。直接删除对应的锁文件:

    rm -f /var/lib/rpm/__db*

    删除锁文件后 , 重新执行 rpm 命令测试

  2. Berkeley DB 数据库损坏 , 重建数据库

    rpm --rebuilddb

    读取 Packages 主表 , 重新生成所有索引文件(Name、Files、Depends 等索引)

    注意 : --rebuilddb 不会删除 Packages 主表 , 只是重建索引 ; 如果 Packages 文件本身损坏严重 , 该命令修复失败。

    重建过程中, 不能断电。重建时不要同时运行 yum/rpm。如果 Packages 主文件损坏 , 重建无效 , 本机包信息丢失 , 只能重装系统。

3. RPM包来源

3.1 发行版官方仓库

系统安装后默认配置的仓库 , 由发行版维护团队打包、测试、签名 , 最安全、依赖最匹配。

CentOS 官方仓库分层

仓库名

含义

内容

BaseOS / Base

基础系统

构成系统核心的软件(glibc、bash、systemd)

AppStream

应用流

用户级应用(httpd、mariadb、python)

Extras / EPEL

扩展

官方仓库没有但常用的软件

Updates

安全更新

已安装软件的修复版本

CR / Stream

持续滚动

CentOS Stream 的滚动更新内容

另外各大知名公司也会提供对应的官方仓库源:

  • https://www.centos.org/download/

  • http://mirrors.aliyun.com

  • http://mirrors.sohu.com

  • http://mirrors.163.com

3.2 第三方公共仓库

大量软件不在官方仓库中 , 由社区或厂商维护

仓库

维护方

擅长领域

安装方式

EPEL

Fedora 社区

海量常用工具(htop、nginx、redis)

yum install epel-release

ELRepo

社区

新内核、硬件驱动

手动导入 GPG key 后装

Remi

Remi Collet

新版 PHP(5.4~8.x 多版本并存)

yum install remi-release

IUS

Rackspace 等

新版 Python/Git/Nginx

手动配置

RPM Fusion

社区

多媒体编解码、闭源驱动(Fedora 系)

手动配置

PostgreSQL 官方

PGDG

新版 PostgreSQL

yum install pgdg-redhat-repo

MySQL/Percona 官方

Oracle/Percona

数据库各分支版本

官网下载 repo 包

以 EPEL 为例(最常用的第三方源)

# CentOS 7:直接装
yum install -y epel-release
​
# 查看来源:这个包本身就在官方 Extras 仓库里
yum info epel-release
​
# 安装后启用
yum clean all
yum makecache

EPEL 全称 Extra Packages for Enterprise Linux , 是 Fedora 项目为 RHEL/CentOS 提供的补充仓库 , 不替代、不冲突官方仓库——官方有的包 EPEL 默认不提供。

仓库冲突问题

多个第三方仓库提供同一个软件的不同版本时 , 会造成冲突:

# 控制优先级,避免仓库打架
yum install -y yum-plugin-priorities   # CentOS 7
​
# 在 repo 文件中加入 priority=1(数字越小优先级越高)
[epel]
name=EPEL
priority=10

最佳实践 : 生产服务器上只启用必要的仓库。装完就禁用(enabled=0) ,避免 yum update 时意外升级。

3.3. 软件官方网站

数据库、中间件、商业软件等通常由厂商直接提供 RPM:

来源

典型软件

获取方式

官网下载页

Nginx Plus、GitLab EE、MySQL Enterprise

官网 → Downloads → RHEL/CentOS 版

官方 repo 包

Zabbix、Docker CE、Nginx OSS、PostgreSQL

下载 xxx-release.rpm 一键配置仓库

订阅客户门户

RHEL 官方软件、Oracle DB

登录后下载或配置订阅仓库

示例, Nginx 官方仓库

# 下载官方仓库配置包(一次性配置好 repo 和 GPG key)
rpm -Uvh https://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
​
# 之后像装普通软件一样安装(版本比官方仓库新)
yum install nginx

这类 *-release.rpm 包的作用 : 自动写入 /etc/yum.repos.d/xxx.repo 并导入 GPG 公钥 , 是官方推荐的接入方式。

3.4 社区聚合网站

网站

用途

pkgs.org

跨发行版 RPM 搜索(最常用)

rpmfind.net

老牌 RPM 搜索引擎

rpm.pbone.net

同上 , 镜像多

koji.fedoraproject.org

Fedora 构建系统,可下载构建产物

使用原则:

  • 用它们定位软件在哪个仓库 → 然后配置仓库用 yum 装

  • 直接下载单个 RPM 手动装是下策(依赖问题、版本错配)

  • 注意选择匹配自己系统的版本 : el7 /el8 /el9 不能混装

3.5 自建来源

  • 本地目录仓库

    mkdir -p /opt/localrepo
    # 放入 rpm 包后生成索引
    createrepo /opt/localrepo
    ​
    # 配置 file:// 协议仓库
    cat > /etc/yum.repos.d/local.repo <<EOF
    [local]
    name=Local RPMs
    baseurl=file:///opt/localrepo
    enabled=1
    gpgcheck=0
    EOF
  • HTTP 内网仓库(企业标准做法)

    # 在内网服务器上
    mkdir -p /var/www/html/repo/centos7
    # 用 reposync 同步公网仓库
    reposync -p /var/www/html/repo --repoid=base --repoid=updates
    createrepo /var/www/html/repo/centos7/base
    ​
    # 客户端配置指向内网
    baseurl=http://repo.internal/centos7/base
  • 打包工具下载(离线依赖收集)

    yum install -y yum-utils
    yumdownloader --resolve --destdir=./rpms nginx   # 下载包及全部依赖

3.6 SRPM自行构建

拿到源码包自己编译 , 适合需要定制编译参数或打补丁的场景:

# 来源:发行版源码仓库 / src.rpm / 官网源码
yum install -y rpm-build rpmdevtools
​
# 方法1:从 SRPM 构建
rpm -ivh nginx-1.24.0-1.el7.src.rpm   # 解到 ~/rpmbuild
rpmbuild -ba ~/rpmbuild/SPECS/nginx.spec
​
# 方法2:用 mock 在干净环境构建(推荐,避免污染系统)
yum install -y mock
mock -r epel-7-x86_64 rebuild nginx-1.24.0-1.el7.src.rpm

4. RPM包管理

rpm 是 Red Hat 系发行版底层的包管理命令行工具。它不自动解决依赖 , 但查询能力极强 , 是系统管理员日常排障、审计、验证的核心武器。

  • 语法 : rpm [选项] [包名或文件]

关键约定:

操作已安装的包 → 用包名(如 httpd , 不带版本号和 .rpm 后缀)

操作未安装的 .rpm 文件 → 加 -p 选项(如 -qpi package.rpm)

4.1 安装

  • 语法 : rpm {-i|--install} [install-options] PACKAGE_FILE...

  • 参数

    • -v : 显示详细过程

    • -h : 显示 # 进度条(50 个#代表完成)

  • install-options

    • --test : 测试安装 , 但不真正执行安装 , 即dry run模式

    • --nodeps : 跳过依赖检查(危险!)

    • --force : 强制安装(覆盖冲突文件)

    • --oldpackage : 允许降级安装

    • --replacepkgs : 重新安装已存在的包

    • --nodigest : 不检查包完整性

    • --nosignature : 不检查来源合法性

    • --nopre : %pre , 不执行安装前脚本 ;

    • --nopos : %post , 不执行安装后脚本 ;

    • --nopreun : %preun , 不执行卸载前脚本 ;

    • --nopostun : %postun ,不执行卸载后脚本 ;

    • --noscripts : 不执行程序包脚本 。 等价于执行上面四个脚本参数

示例:

批量安装

rpm -ivh *.rpm                    # 当前目录下所有 rpm
rpm -ivh --test *.rpm             # 先检查全部,确认无冲突再真装

其他

# 强制重装(文件丢失,想还原包原始文件)
rpm -ivh --force nginx-1.20.1-1.el7.x86_64.rpm
​
# 忽略依赖强制安装(测试环境临时用,生产禁止)
rpm -ivh --nodeps nginx-1.20.1-1.el7.x86_64.rpm

4.2 升级

  • 语法

    rpm {-U|--upgrade} [install-options] PACKAGE_FILE... 
    rpm {-F|--freshen} [install-options] PACKAGE_FILE... 

    Upgrade : 表示已安装则升级 , 未安装则直接安装

    Freshen : 仅当已安装且版本更新时才处理

  • install-options

    • --force : 强制安装(覆盖冲突文件)

    • --oldpackage : 允许降级安装

注意 :

  1. 不要对内核做升级操作 ; Linux支持多内核版本并存 , 因此 , 对直接安装新版本内核 。-U 会删除旧内核 , 一旦新内核起不来 , 系统无法启动。

  2. 如果原程序包的配置文件安装后曾被修改 , 升级时 , 新版本 的提供的同一个配置文件并不会直接覆盖老版本的配置文件 , 而 把新版本的文件重命名(FILENAME.rpmnew)后保留

示例

# 升级包,不存在则直接安装
rpm -Uvh nginx-1.22.0-1.el7.x86_64.rpm
​
​
# 仅升级本机已存在的nginx;本机没有nginx则不执行
rpm -Fvh nginx-1.22.0-1.el7.x86_64.rpm

4.3 卸载

  • 语法 : rpm {-e|--erase} [--allmatches] [--nodeps] [-noscripts] [--notriggers] [--test] PACKAGE_NAME ...

卸载时会检查其他包是否依赖当前包 ;有依赖则直接报错 , 不会自动删除依赖包

这个命令不同于安装和升级 , 它可以在任何目录运行 , 原理是去/var/lib/rpm目录中的数据库 ( 如__db0 ) 中查找对应的软件包 ( 已经安装过的rpm包都在这些数据库中 ) ,然后卸载。

示例:

rpm -e httpd              # 卸载(只写包名!)
rpm -e httpd --nodeps     # 跳过依赖检查(危险:依赖它的程序会坏)
rpm -e --justdb httpd     # 只从数据库删除记录,不删实际文件
rpm -e --noscripts httpd  # 跳过卸载脚本(脚本写错导致无法卸载时的救命选项)

卸载失败

# 报错:package httpd is needed by (installed) httpd-tools-2.4.x
# 说明 httpd-tools 依赖 httpd,必须先卸载 httpd-tools
rpm -e httpd-tools httpd   # 一起卸载,或先卸依赖方

4.4 RPM包查询

  • 语法: rpm {-q|--query} [select-options] [query-options]

  • [select-options]

    • -a: 所有包

    • -f: 查看指定的文件由哪个程序包安装生成

    • -p rpmfile : 针对尚未安装的程序包文件做查询操作

    • --whatprovides CAPABILITY : 查询指定的CAPABILITY 由哪个包所提供

    • --whatrequires CAPABILITY : 查询指定的CAPABILITY被 哪个包所依赖

  • [query-options]

    • --changelog : 查询rpm包的changelog

    • -c : 查询程序的配置文件

    • -d : 查询程序的文档

    • -i : 详细信息:版本、描述、打包者、安装时间、签名

    • -l : 查看指定的程序包安装后生成的所有文件

    • --scripts : 程序包自带的脚本

    • --provides : 列出指定程序包所提供的CAPABILITY

    • -R : 查询指定的程序包所依赖的CAPABILITY

rpm2cpio 包文件|cpio –itv : 预览包内文件

rpm2cpio 包文件|cpio –idv "*.conf" : 释放包内文件

rpm2cpio tree-1.60-10.el7.x86_64.rpm |cpio -id ./usr/bin/tree 指定生成的文件 至生出对应的文件目录

常见用法 :

-qi PACKAGE   -qf FILE
-qc PACKAGE   -ql PACKAGE
-qd PACKAGE   -qpi PACKAGE_FILE
-qpl PACKAGE_FILE, ...  -qa 

示例 :

包详细信息

rpm -qi httpd             # 详细信息:版本、描述、打包者、安装时间、签名
rpm -ql httpd             # 列出该包安装的所有文件
rpm -qd httpd             # 只列出文档文件(man、README)
rpm -qc httpd             # 只列出配置文件
rpm -qR httpd             # 列出依赖(Requires)
rpm -q --scripts httpd    # 查看安装/卸载脚本内容
rpm -q --changelog httpd  # 查看打包变更记录
rpm -q --triggers httpd   # 查看触发器脚本

反查文件归属

rpm -qf /usr/sbin/nginx           # 这个文件属于哪个包
rpm -qf /etc/passwd               # 系统文件归属
rpm -qf $(which python3)          # 配合 which 查命令来源

查询未安装的 rpm 文件

rpm -qpi package.rpm      # 查看文件包的信息
rpm -qpl package.rpm      # 查看文件包会装哪些文件
rpm -qpR package.rpm      # 查看文件包的依赖
rpm -qpc package.rpm      # 查看文件包的配置文件
rpm -qpd package.rpm      # 查看文件包的文档

依赖反向查询

rpm -q --whatrequires openssl       # 谁依赖 openssl(已安装范围内)
rpm -q --whatprovides /usr/bin/perl # 谁提供这个文件/能力
rpm -q --whatprovides 'libssl.so.1.1()(64bit)'

4.5 包校验

  • 语法 : rpm {-V|--verify} [select-options] [verify-options]

校验已经安装包

rpm -V httpd              # 校验单个包
rpm -Va                   # 校验所有包(安全审计神器)
rpm -Va 2>/dev/null | grep -v '^..5'   # 只看内容被改过的文件
​
​
#输出
S.5....T.  c /etc/nginx/nginx.conf

默认没有输出结果。如果校验有输出, 按照以下字符比较, 可以判断对应的配置文件改变的地方。

字符

含义

S

文件大小改变

M

模式(权限)改变

5

MD5/SHA 摘要校验失败(内容被改)

D

设备文件主/次设备号改变

L

符号链接指向改变

U

属主改变

G

属组改变

T

修改时间改变

P

capabilities 改变

输出格式中c表示配置文件。其他参考以下内容。

c(config file) : 配置文件
d(documentation) : 普通文档
g(ghost file) : "鬼"文件, 很少见, 就是该文件不应该被这个RPM包包含
L(license file) : 授权文件
r(read me) : 描述文件

示例 : 执行 rpm -V httpd 后, 无任何提示, 代表该文件没有被做任何修改

  1. 判断本地的apache 与官方给出的是否一致, 从而判断是否被人修改。

  2. 修改文件 /etc/httpd/conf/httpd.conf ,

  3. 在注释行添加任意内容后, 再次执行 , 执行结果如下图所示

    RPM -V

校验本身需要导入公钥信息

# 查看系统已导入的公钥
rpm -qa gpg-pubkey*
​
# 查看某公钥详情
rpm -qi gpg-pubkey-f4a80eb5-53a7ff4b
​
# 导入仓库公钥
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
rpm --import https://nginx.org/keys/nginx_signing.key
​
# 删除公钥
rpm -e gpg-pubkey-f4a80eb5-53a7ff4b

rpm -qa “gpg-pubkey*” 查询安装的公钥软件

4.6 RPM数据库重建

  • 语法 : rpm {--initdb|--rebuilddb}

    • initdb: 初始化 如果事先不存在数据库 , 则新建之 否则 , 不执行任何操作

    • rebuilddb : 重建已安装的包头的数据库索引目录

示例:

重建数据库 。适用场景: 索引文件损坏但 Packages 完好; 大量卸载后数据库膨胀; BDB → SQLite 格式转换

rpm --rebuilddb           # 重建索引(从 Packages 主文件重新生成所有索引)
rpm --rebuilddb -v        # 显示详细过程

初始化空数据库。(空数据库意味着系统"忘记"了所有已安装的包。仅在极端排障场景使用。)

rpm --initdb              # 创建全新的空数据库

验证数据库的完整性

rpm --verifydb            # 验证数据库内部一致性

数据库损坏修复

# 第 0 步:备份
cp -a /var/lib/rpm /var/lib/rpm.backup.$(date +%s)
​
# 第 1 步:清理残留锁文件
rm -f /var/lib/rpm/__db.*
​
# 第 2 步:验证主文件
/usr/lib/rpm/rpmdb_verify /var/lib/rpm/Packages
​
# 第 3 步:若损坏,dump/load 修复
mv /var/lib/rpm/Packages /var/lib/rpm/Packages.orig
/usr/lib/rpm/rpmdb_dump Packages.orig | /usr/lib/rpm/rpmdb_load Packages
/usr/lib/rpm/rpmdb_verify Packages
​
# 第 4 步:重建索引
rpm --rebuilddb -v
​
# 第 5 步:验证
rpm -qa > /dev/null


熊熊