rpm包缺失时,根本原因在于本地源未覆盖所有依赖层级,yum localinstall仅解决显式依赖,不处理传递依赖;需用createrepo构建本地源并启用对应仓库。
rpm包缺失时,直接用 yum localinstall 或 dnf install --allowerasing *.rpm 往往不能真正解决问题——根源不在安装命令,而在本地源未覆盖构建/运行所需的所有依赖层级。
为什么 yum localinstall 仍会报“xxx is not installed”?
因为 yum localinstall 只解决“已下载 RPM 包的显式依赖”,但不自动拉取这些依赖的依赖(即 transitive dependencies)。尤其当你的 RPM 是从非标准渠道编译(如自建 SPEC、mock 构建)而来时,Requires 字段可能指向仓库里不存在的包名(比如 libgrass_rli.so()(64bit)),或依赖版本与当前系统仓库不匹配。
- 典型错误:
error: package grass-6.4.4-1.el6.x86_64 requires libgrass_rli.so()(64bit)—— 这个 so 不在 base 仓库,而是在 EPEL 或第三方 repo - 真实场景:你拿到一个别人编译好的
myapp-1.2-1.fc38.x86_64.rpm,在干净的 CentOS Stream 9 上执行yum localinstall,结果卡在python3.11dist(pydantic) - 根本原因:本地没启用对应源,或源里没同步该包的元数据(
repodata缺失/过期)
快速补全本地源:三步生成可工作的 file:// 源
不用改 /etc/yum.repos.d/,也不用搭 HTTP 服务,直接用 createrepo 在本地目录建一个最小可用源。
- 把所有要装的 RPM(含你自己的 + 从其他机器
yumdownloader --resolve拉来的依赖)统一放进/tmp/myrepo/ - 运行:
createrepo -v /tmp/myrepo/—— 它会生成repodata/目录,这是 yum/dnf 能识别的关键 - 创建 repo 文件:
/etc/yum.repos.d/local.repo,内容只写三行:[local] name=Local RPMs baseurl=file:///tmp/myrepo/ enabled=1 gpgcheck=0
- 刷新缓存:
dnf makecache,再试dnf install myapp-1.2-1.fc38.x86_64.rpm,依赖就能自动解析了
yumdownloader --resolve 和 dnf download --alldeps 的关键区别
两者都用来批量下载依赖,但行为差异直接影响你能否一次配齐:
-
yumdownloader --resolve(RHEL/CentOS 7/8):只下载当前系统已启用仓库中的依赖,不会跨架构(比如不拉 aarch64 包到 x86_64 主机),且对BuildRequires无感知 -
dnf download --alldeps(Fedora/RHEL 9+):默认启用--source以外的所有 repo,支持--archlist指定目标架构,更可靠;但若 RPM 的Requires写的是虚拟提供(如python3dist(requests)),仍需确保对应python3-requests包已存在于启用的源中 - 实操建议:先用
rpm -qpR myapp.rpm看清所有Requires,再对照dnf repoquery --whatprovides "python3dist(requests)"验证是否能命中 —— 别等安装时报错才回头查
别跳过 mock:干净环境才是依赖问题的照妖镜
你在本机 yum install 成功,不代表 RPM 包真的“自带完整依赖”。很多包靠本机已装的开发库、头文件、甚至 /usr/local/bin 下的手动编译工具链“侥幸通过”,一换机器就崩。
- 用
mock -r epel-9-x86_64 --rebuild myapp.src.rpm构建一次,mock 会严格按 SPEC 中的BuildRequires初始化 chroot,任何漏写的依赖都会立刻暴露为 configure/make 错误 - 构建成功后,进入 mock 根目录:
/var/lib/mock/epel-9-x86_64/root/,运行rpm -qa | sort > pkg-list.txt—— 这份清单就是你最终部署时必须保证存在的最小包集合 - 最容易被忽略的一点:mock 默认不包含
epel-release,如果你的 SPEC 依赖 EPEL 包,得先mock -r epel-9-x86_64 --init && mock -r epel-9-x86_64 --install epel-release,再 rebuild
依赖问题从来不是“少装一个包”的事,而是“声明是否完整 + 源是否可达 + 环境是否隔离”的三角验证。mock 里跑不过的包,就算你用 --nodeps 强装进生产机,迟早会在某个 systemctl reload 时静默失败。










