拆开一个 .rpm 文件,里面到底装了什么?

拆开一个 .rpm 文件,里面到底装了什么?

你天天在终端敲 dnf install vim,下载下来那个 vim-common-8.2-xxx.rpm 文件,你打开过吗?

在文件管理器里双击它,多半打不开;用 cat 看一眼,满屏乱码。它既不是可执行程序,也不是你熟悉的 .tar.gz 压缩包。那它到底是什么?

今天我们就亲手把它拆开,看看这个天天见、却从没真正看过的东西,肚子里到底装了什么。


一、先动手,别空想

与其猜,不如直接上命令。随便找一个本地的 rpm 包(或者 dnf download vim-common 下一个):

bash 复制代码
$ file vim-common-8.2-10.el8.x86_64.rpm
vim-common-8.2-10.el8.x86_64.rpm: RPM v3 bin package

系统告诉我们:这是个 RPM 包。但里面有什么,它没说。接着拆:

bash 复制代码
$ rpm2cpio vim-common-8.2-10.el8.x86_64.rpm | cpio -idmv
./usr/bin/xxd
./usr/share/doc/vim-common/...
./usr/share/man/man1/xxd.1.gz
...

rpm2cpio 把包里的文件流解出来,cpio 负责把文件铺回目录------于是你看到一堆散落的文件。

可问题来了:安装信息在哪?vim-common 的版本号、它依赖什么、装的时候要跑什么脚本------这些 cpio 一个都没解出来。它们不在文件系统里,而藏在包自己的"头"上。

再用 RPM 自带的命令看一眼:

bash 复制代码
$ rpm -qpi vim-common-8.2-10.el8.x86_64.rpm          # 包信息:名称/版本/摘要/厂商
$ rpm -qpR vim-common-8.2-10.el8.x86_64.rpm          # 依赖:它需要什么
$ rpm -qp --scripts vim-common-8.2-10.el8.x86_64.rpm # 脚本:装/卸时跑什么

这些 rpm2cpio 解不出来的东西,才是 RPM 最关键的资产。下面看它藏在哪。


二、.rpm 文件是四层叠起来的

一个 .rpm 文件,从外到内其实是四层(见下图):

graph TD A[&#34;Lead 引导区<br/>96字节 · 识别用&#34;] --> B[&#34;Signature Header 签名头<br/>GPG/RSA 防伪&#34;] B --> C[&#34;Header 包头(核心)<br/>包名/版本/依赖/文件列表/脚本&#34;] C --> D[&#34;Payload 载荷<br/>cpio 归档 + 压缩(gzip/xz/zstd)&#34;] style C fill:#ffe0b2,stroke:#f59e0b,stroke-width:2px
  • Lead(引导区):最前面 96 字节,放魔数和基本标识,纯粹用来让系统快速认出"这是个 RPM 包"。对我们理解功能没啥用,可忽略。
  • Signature Header(签名头):包的"身份证防伪页"。里面是 GPG/RSA 签名和校验值,用来证明"这包确实出自可信来源、没被篡改"。回扣上一篇说的"验身份"。
  • Header(包头,核心) :包的"户口本",也是元数据真正所在。它记着:
    • 包名、版本、架构;
    • 依赖关系(Requires 我需要什么 / Provides 我能提供什么);
    • 文件列表,以及每个文件的权限、大小、校验值;
    • 安装/卸载脚本(pre / post / preun / postun)。
  • Payload(载荷) :真正的文件内容,是一个 cpio 归档 ,外面再套一层压缩(gzip / xz / zstd)。前面 rpm2cpio 解出来的那些文件,全在这儿。

一句话记住结构:Lead 认门、Signature 验身、Header 记户口、Payload 装人。


三、RPM 包 ≠ 普通压缩包

到这里,最关键的一个认知出来了:

普通压缩包(比如 .tar.gz)只装文件;RPM 包 = 文件 + 元数据,而且元数据才是它的灵魂。

为什么这么说?因为 RPM 那些"超能力",全靠 Header 里的元数据:

  • dnf 能自动帮你装依赖,是因为 Header 里写清了"我需要什么、谁能提供什么";
  • rpm -V 能发现文件被改过,是因为 Header 里给每个文件存了校验值做对照;
  • 装包时会自动跑脚本,是因为脚本也记在 Header 里。

如果只看 Payload(那堆 cpio 文件),RPM 跟一个普通压缩包没区别。真正的" intelligence "在 Header。


四、收尾 + 预告

所以,下次你再 dnf install 一个包,心里可以有数了:下载下来的那个 .rpm,本质上就是"一段 cpio 文件归档 + 一份写满元数据的包头",外面再用签名扎一道口。

那装到系统上之后,RPM 又是怎么记住"你装了哪些包、每个包有哪些文件"的?下一篇,我们讲 rpm 数据库

相关推荐
wuminyu1 小时前
JDK21 FFM异步读取MSG_ZEROCOPY错误队列揭秘
java·linux·c语言·jvm·c++
Eloudy1 小时前
sunshine - ubuntu 22.04, moonlight - mac OS26 远程桌面
linux·运维·ubuntu
苍狗T1 小时前
K8s 集群实战:基于 Harbor 私有仓库 + cri‑dockerd 完整部署
linux·运维·云原生·容器·kubernetes
石小千1 小时前
X86下载 ARM 架构的包
linux·运维
殷忆枫1 小时前
嵌入式Linux下基于FFmpeg实现MP4解码为JPG图片(SSD202D交叉编译实战)
linux·运维·ffmpeg
牢姐与蒯2 小时前
Linux进程(二)之进程概念
linux·运维·服务器·ubuntu
草莓熊Lotso2 小时前
【Redis 初阶】Hash 类型深度解析:结构化数据存储的最优解
linux·网络·数据库·redis·tcp/ip·缓存·哈希算法
jieshenai2 小时前
Shell 脚本如何定位项目根目录——从一个 8 行的小脚本讲起
linux·运维
迷途之人不知返2 小时前
自制第一个Linux小程序——进度条
linux