rpm 说装好了程序却跑不起来:一次 Linux yum 依赖与 --nodeps 强装的复盘

在 CentOS 7 上装一个第三方监控 agent,yum install 报一串依赖缺失装不上,急着上线就用 rpm -ivh --nodeps --force 强行装上了,rpm -q 查得到以为装好了,几天后 agent 启动失败日志报 error while loading shared libraries libssl.so.10 cannot open shared object file。排查梳理:rpm 是底层工具只管单个包的安装查询卸载会检查依赖但不解决依赖,yum 是上层工具自动解析整张依赖网下载所有需要的包按序调 rpm 装上,装软件永远优先 yum;依赖写在包元数据里 Requires 列我需要什么 Provides 列我提供什么,yum 解析依赖就是拿 Requires 去匹配别的包的 Provides,rpm -qR 看需求 --whatprovides 和 yum provides 反查谁提供;--nodeps 跳过的只是检查依赖这个动作丝毫没有满足依赖,缺的东西该缺还是缺,rpm --nodeps 装完数据库登记了 rpm -q 查得到但依赖没就位是个一运行就崩的半成品,数据库里在册不等于运行时能跑;依赖缺失的正解是补齐不是绕过 yum provides 反查后配好仓库让 yum 自己解,装本地 rpm 文件用 yum localinstall 会自动解依赖别用 rpm -ivh;第三方源混用会让 yum 为满足依赖顺手升级 openssl glibc 等系统关键库导致一批旧程序集体崩,防线是装前逐行看 yum 清单盯紧 Updating 段 用 priorities 给官方源更高优先级 versionlock 锁死关键包 第三方源平时 enabled=0。正确做法是装好要 ldd 验证没有 not found,以及一套 rpm yum 依赖排查纪律。

2022 年,一次"我明明用 rpm 把软件装好了、rpm -q 也查得到,可它一跑就崩"的事故,把我对"一个软件,装好了"这件事的理解,彻底翻新了一遍。那天我要在一台 CentOS 7 上,装一个监控 agent。我老老实实 yum install,结果它报了一串依赖缺失:缺这个库、缺那个库。我当时急着上线,在网上搜了一圈,看到一句"加上 --nodeps 就能强装",如获至宝。我下载了那个 rpm 包,敲下 rpm -ivh --nodeps --force xxx.rpm——干净利落,装上了。我 rpm -q 一查,那个 agent 的名字、版本号,白纸黑字,清清楚楚地列在那儿。我心满意足:装好了。可几天后,这个 agent 起不来了,日志里就一行刺眼的字:error while loading shared libraries: libxxx.so.1: cannot open shared object file。我整个人懵了:我装的时候,rpm 没报一个错;我查的时候,rpm -q 明明白白告诉我"它在";一个"装好了的、查得到的"软件,怎么会因为"找不到一个库",就跑不起来?我盯着那行报错,第一次开始怀疑:rpm -q 告诉我的那个"装好了"——它到底是什么意思?它说的"装好了",和我以为的"这个程序真的能跑起来",是同一件事吗?这件事逼着我把 rpmyum 的关系、什么是依赖、--nodeps 的真正危害、第三方源冲突这一整套彻底理清了。本文复盘这次实战。

问题背景

环境:CentOS 7,要装一个第三方监控 agent
事故现象:
- yum install 报一串依赖缺失,装不上
- ★ 我用 rpm -ivh --nodeps --force 强行装上了
- ★ rpm -q 查得到,以为"装好了"
- 几天后 agent 启动失败,日志:
  error while loading shared libraries:
  libxxx.so.1: cannot open shared object file

现场排查:
# 1. rpm 查这个包 —— 它"在"
$ rpm -q monitor-agent
monitor-agent-2.3.1-1.el7.x86_64               # ★ 查得到

# 2. ★ 可它一跑就崩
$ /opt/monitor-agent/bin/agent
/opt/monitor-agent/bin/agent: error while loading
shared libraries: libssl.so.10: cannot open
shared object file: No such file or directory
# ★ 它要一个 libssl.so.10,系统上没有。

# 3. ★ 关键:查这个 rpm 包,到底"需要"什么
$ rpm -qR monitor-agent
libssl.so.10()(64bit)                          # ★★ 它需要这个!
libcrypto.so.10()(64bit)
glibc >= 2.17
...
# ★ 包自己写得明明白白:我需要 libssl.so.10。

# 4. ★ 系统上,到底有没有这个库
$ ldconfig -p | grep libssl
libssl.so.1.1 (libc6,x86-64) => /usr/lib64/libssl.so.1.1
# ★ 系统上只有 libssl.so.1.1,【没有】libssl.so.10。
# ★ 那个包要的 .10,根本不存在。

# 5. ★ 回想:我当初是怎么"装好"的
$ rpm -ivh --nodeps --force monitor-agent-2.3.1.rpm
#   ★ --nodeps —— 我当初就是用它,跳过了依赖检查。

根因(后来想清楚的):
1. ★ 这个 rpm 包,真正运行需要 libssl.so.10。这是
   它的【依赖】—— 写在包的元数据里。
2. ★ yum install 当初报"依赖缺失",报的就是这个:
   系统上没有 libssl.so.10,装了也跑不了。yum 是
   在【提前拦住我】。
3. ★ 我用 --nodeps,等于对 rpm 说:"别检查依赖,
   直接装。" rpm 照做了 —— 它把文件拷进系统,在
   【rpm 数据库】里登记了一笔"monitor-agent 已安装"。
4. ★ 但 --nodeps 跳过的,只是"检查"这个动作。它
   【没有、也不可能】凭空把 libssl.so.10 变出来。
   那个依赖,该缺还是缺。
5. ★ 于是:rpm 数据库说"装好了"(登记了),可
   程序一运行,真去找 libssl.so.10,找不到 —— 崩。
6. 真相:rpm -q 查到的"装好了",只是"rpm 数据库里
   有这条登记"。它【不代表】这个程序运行需要的
   一切都就位了。
不是包坏了,是我用 --nodeps 跳过了依赖检查,
让一个"依赖根本不满足"的包,假装"装好了"。

修复 1:rpm 与 yum——一个管单个包,一个管整张依赖网

# === ★ 先把这两个工具的分工讲清楚 ===

# === ★ rpm:最底层的"包安装/查询"工具 ===
# rpm 是 RedHat 系的【底层】包管理器。它干的事,
#   非常"单纯":
#  - 把一个 .rpm 文件里的内容,拷进系统该去的位置;
#  - 在【rpm 数据库】里,登记一笔"这个包装了";
#  - 查询、卸载某个【具体的包】。
$ rpm -ivh xxx.rpm        # 安装一个具体的 rpm 文件
$ rpm -q xxx              # 查某个包装没装
$ rpm -e xxx              # 卸载一个包
# ★ 关键:rpm 的视野,只有【你手里这一个包】。它
#   【不会】自动帮你去下载、解决这个包需要的其它包。

# === ★ rpm 会"检查"依赖,但不会"解决"依赖 ===
# rpm 安装时,会读包的元数据,看它依赖什么、系统
#   满不满足。不满足 —— 它会【报错、拒绝安装】。
# ★ 但 rpm 能做的,仅止于"报错拦住你"。它【不会】
#   自己跑去把缺的依赖找来装上 —— 那不是它的活。

# === ★ yum:在 rpm 之上,负责"解决整张依赖网" ===
# yum(新系统是 dnf)是【上层】工具。你让它装一个
#   包,它会:
#  1. 去【配置好的仓库(repo)】里,找这个包;
#  2. ★ 读这个包的依赖,发现还缺 A;再读 A 的依赖,
#     发现还缺 B…… 把整张【依赖网】全捋清楚;
#  3. 把这一整串包,全部下载下来;
#  4. ★ 按正确的顺序,挨个调用 rpm 装上。
$ yum install monitor-agent
# ★ 一句话:yum 负责"想清楚要装哪些",rpm 负责
#   "把其中每一个,实际装下去"。

# === ★ 所以这俩是"上下级",不是"二选一" ===
# yum 的底层,就是 rpm。你 yum install 一个东西,
#   最终还是 yum 在背后一个个调 rpm。
# ★ 平时安装软件,【永远优先用 yum】—— 因为只有它
#   会自动解决依赖。直接用 rpm 装,你就得自己当
#   "人肉依赖解析器",极易出本文这种事。

# === ★ 回到本文:我犯的错,就是越级用了 rpm ===
# yum install 报依赖缺失 —— 这是 yum 在尽职:它
#   发现依赖网补不齐,正确地拒绝了。
# ★ 我却绕过 yum,直接用底层的 rpm + --nodeps 硬来。
#   我亲手放弃了 yum 唯一的、最重要的价值:依赖解析。

# === 认知 ===
# ★ rpm 是底层工具,只管单个包的安装/查询/卸载,
#   会检查依赖但不会解决依赖;yum 是上层工具,自动
#   解析整张依赖网、下载并按序调 rpm 装上。装软件
#   永远优先用 yum,直接 rpm 装就得自己背依赖。

修复 2:依赖到底是什么——Requires 与 Provides

# === ★ "依赖"不是个抽象词,它是包里写死的元数据 ===

# === ★ 每个 rpm 包,都带两份"清单" ===
# 一个 rpm 包,除了文件本身,还带着一份元数据,其中
#   最关键的是两份清单:
#  - ★ Requires(我需要什么):列出这个包要正常工作,
#    必须有的东西 —— 别的包、或某个具体的库文件。
#  - ★ Provides(我提供什么):列出这个包装上后,
#    会给系统"提供"哪些东西 —— 比如它装了哪些库。

# === ★ 看一个包"需要"什么 ===
$ rpm -qR monitor-agent
libssl.so.10()(64bit)        # ★ 需要这个库文件
libcrypto.so.10()(64bit)
glibc >= 2.17                # ★ 需要 glibc,且版本 ≥ 2.17
/bin/sh
# ★ -qR = query Requires。这就是这个包的"需求清单"。

# === ★ 看一个包"提供"什么 ===
$ rpm -q --provides openssl-libs
libssl.so.1.1()(64bit)       # ★ 它提供的是 .1.1
libcrypto.so.1.1()(64bit)
openssl-libs = 1:1.1.1k-...
# ★ 注意!本文系统上的 openssl-libs,Provides 的是
#   libssl.so.1.1。而 monitor-agent Requires 的是
#   libssl.so.10。★ 一个要 .10,一个给 .1.1 ——
#   对不上。依赖,就是这么"缺"的。

# === ★ yum 解析依赖,就是在做"连连看" ===
# yum 的依赖解析,本质就是:拿着 A 包的每一条
#   Requires,去所有仓库里找"谁的 Provides 能满足
#   它"。
#  - 找得到 -> 把那个包也加入安装列表,再去解析它;
#  - ★ 全部仓库都找不到 -> 报"依赖缺失",装不了。
# ★ 本文 yum install 报错,就是这一步:它拿着
#   libssl.so.10 这条 Requires,翻遍所有仓库,没有
#   任何包 Provides 它 —— 于是如实报告"缺依赖"。

# === ★ 反查:系统上,谁提供了某个库 ===
$ rpm -q --whatprovides 'libssl.so.1.1()(64bit)'
openssl-libs-1.1.1k-...                  # ★ 是 openssl-libs 提供的
$ yum provides '*/libssl.so.10'          # 在仓库里找谁提供 .10
# ★ 排查"缺某个库",就用 whatprovides / yum provides
#   反查 —— 它能告诉你"该装哪个包,才能补上这个库"。

# === ★ 为什么 .so.10 和 .so.1.1 不能混用 ===
# 库文件名里的数字,是【ABI 版本号】。.so.10 和
#   .so.1.1 是【两个不兼容的大版本】。一个程序编译时
#   链接的是 .10,运行时就【只认 .10】,你给它 .1.1,
#   它不认 —— 就像钥匙和锁,版本对不上,插不进。
# ★ 所以依赖不是"有个差不多的库就行",是【名字和
#   版本都得精确对上】。

# === 认知 ===
# ★ 依赖是写在 rpm 包元数据里的硬信息:Requires 列
#   "我需要什么",Provides 列"我提供什么"。yum 解析
#   依赖,就是拿 Requires 去匹配别的包的 Provides。
#   rpm -qR 看需求、--whatprovides / yum provides
#   反查谁能满足 —— 这是排查依赖问题的基本功。

修复 3:--nodeps 的真正危害——"登记了"不等于"能跑"

# === ★ 本文最核心的认知:--nodeps 到底跳过了什么 ===

# === ★ --nodeps 字面意思:别检查依赖 ===
$ rpm -ivh --nodeps --force xxx.rpm
# ★ --nodeps = no dependencies check。它告诉 rpm:
#   "安装时,别去检查依赖满不满足,直接装。"
# ★ --force = 强制,连"文件冲突""已装过"也无视。

# === ★ 关键的误解:我以为 --nodeps 是"解决"了依赖 ===
# 我当初的想法是:"yum 嫌依赖不够不让装,我用
#   --nodeps 让它别管 —— 问题不就解决了?"
# ★ 这是个致命的误解。--nodeps 跳过的,是【检查
#   依赖】这个【动作】。它【完全没有】去碰"依赖
#   本身满不满足"这个【事实】。

# === ★ 一个类比:--nodeps 是"把体检报告撕了" ===
# yum/rpm 检查依赖,像一次"体检":告诉你身体缺什么。
# ★ --nodeps 不是"把病治好了",它只是【把体检报告
#   撕掉,不看了】。病,一点没好。
# ★ 你撕掉报告,确实能"顺利"走出医院(装"成功"了);
#   可那个缺的依赖,就像没治的病,迟早发作。

# === ★ 于是,装出来的是个什么东西 ===
# rpm --nodeps 装完后:
#  - ★ 文件:确实拷进系统了。
#  - ★ rpm 数据库:确实登记了一笔"monitor-agent 已装"。
#  - ★ 所以 rpm -q 查得到 —— 它查的就是这个数据库。
#  - ★ 但 libssl.so.10 这个依赖 —— 系统上【依然
#    没有】。--nodeps 没变出来,也变不出来。
# ★ 结果就是一个"半成品":登记在册,却缺胳膊少腿。

# === ★ "装好了"其实是两件不同的事 ===
# ★ 第一件:rpm 数据库里,有它的登记。(行政意义上
#   的"在册")
# ★ 第二件:它运行时需要的一切(依赖的库、文件),
#   系统上都【真的就位】了。(事实意义上的"能跑")
# ★ 正常 yum 装,这两件【一起】成立。--nodeps 强装,
#   只做到了第一件 —— 数据库登记了,事实没就位。
# ★ rpm -q 查的,永远是第一件。它"查得到",绝不
#   等于第二件成立。本文的崩溃,就崩在第二件上。

# === ★ 什么时候,--nodeps 才是"碰巧没事" ===
# --nodeps 装的包,如果它依赖的东西【碰巧】系统上
#   全都有 —— 那它也能跑。这时 --nodeps 看着"管用"。
# ★ 但这是【侥幸】,不是【正确】。你赌的是"它要的
#   依赖恰好都在"。一旦赌输(像本文),就是运行时
#   崩溃,而且崩在你最没防备的时候。

# === ★ --nodeps 真正的、极少数的正当用途 ===
# 它不是绝对不能用,但只在很专业的场景:比如你
#   【明确知道】某条 Requires 是包打错了(误报),
#   或你要用别的方式提供那个依赖。
# ★ "急着上线、不想解决依赖" —— 这【不是】正当
#   用途,这是给未来埋雷。

# === 认知 ===
# ★ --nodeps 跳过的只是"检查依赖"这个动作,它丝毫
#   没有"满足依赖"。rpm --nodeps 装完,数据库登记
#   了(rpm -q 查得到)但依赖实际没就位,装出一个
#   一运行就崩的半成品。"数据库里在册" ≠ "运行时
#   能跑",这是两件必须分开看的事。

修复 4:依赖缺失的正确解法——让 yum 自己去解

# === ★ yum 报依赖缺失,正道是"补齐",不是"绕过" ===

# === ★ 第一步:看清楚,到底缺什么 ===
# yum install 报依赖缺失时,别急着 --nodeps。先把
#   报错看仔细 —— 它会明确说缺哪个包/哪个库:
$ yum install monitor-agent
...
Error: Package: monitor-agent-2.3.1.el7.x86_64
       Requires: libssl.so.10()(64bit)
# ★ 这行就是答案:它要 libssl.so.10。

# === ★ 第二步:反查,哪个包能提供这个东西 ===
$ yum provides '*/libssl.so.10'
openssl10-libs-1.0.2k-...  : ...
   Repo: epel
# ★ 哦,EPEL 仓库里有个 openssl10-libs 能提供它。
# ★ 那正解就是:先把这个仓库配好,让 yum 能找到
#   openssl10-libs,然后 yum 会【自己】把它一起装上。

# === ★ 第三步:配好仓库,让 yum 一次解决 ===
$ yum install epel-release        # 例:启用 EPEL 源
$ yum install monitor-agent       # ★ 再装一次 —— 这次
#   yum 能找到 openssl10-libs 了,会自动连它一起装。
# ★ 这才是正道:不是"让 rpm 别检查",而是"给 yum
#   补上它需要的仓库,让它有能力把依赖网解全"。

# === ★ 装本地 rpm 文件,也要用 yum,别用 rpm ===
# 如果你手里就是一个 .rpm 文件,想装它 —— ★ 不要
#   rpm -ivh。用 yum localinstall(或新版 yum install
#   直接给路径):
$ yum localinstall ./monitor-agent-2.3.1.rpm
# ★ 区别巨大:yum localinstall 装这个本地文件时,
#   会【自动去仓库解决它的依赖】;rpm -ivh 只会
#   装这一个文件,依赖缺了就报错(或被你 --nodeps
#   跳过)。同样是装本地包,yum 帮你解依赖,rpm 不会。

# === ★ 实在没有仓库?也要手动"装全",不是跳过 ===
# 极端情况:某依赖任何仓库都没有。正确做法仍是
#   【想办法把那个依赖弄到、装上】(找到对应 rpm、
#   或换一个依赖匹配的软件版本),而【不是】
#   --nodeps 把它跳过。
# ★ 核心原则:依赖缺失,要解决的是"缺"这个事实,
#   不是"报错"这个现象。

# === ★ 验证:这次是真的装好了 ===
$ rpm -q monitor-agent           # ① 数据库里有
monitor-agent-2.3.1-1.el7.x86_64
$ ldd /opt/monitor-agent/bin/agent | grep 'not found'
(无输出)                        # ★ ② 它依赖的库,全部找得到
$ /opt/monitor-agent/bin/agent --version
agent 2.3.1                      # ★ ③ 真的能跑起来
# ★ 三个都过 —— 在册 + 依赖就位 + 能跑,这才叫装好。

# === 认知 ===
# ★ yum 报依赖缺失,正解是"补齐依赖":看清缺什么、
#   yum provides 反查谁提供、配好对应仓库让 yum 自己
#   解。装本地 rpm 文件用 yum localinstall(会自动
#   解依赖),别用 rpm -ivh。要解决的是"缺"这个
#   事实,不是"报错"这个现象。

修复 5:第三方源混用——依赖被悄悄"打架"升级

# === ★ 依赖问题的另一张面孔:不是缺,是"冲突" ===

# === ★ 场景:装个新软件,yum 顺手升级了别的东西 ===
# 你 yum install 一个新软件,看 yum 列出的清单时,
#   ★ 多留个心眼 —— 它常常不只装你要的那个:
$ yum install some-new-tool
...
Installing:
 some-new-tool       x86_64   ...   third-party-repo
Updating for dependencies:                       # ★★ 注意这段!
 openssl             x86_64   ...   third-party-repo
 openssl-libs        x86_64   ...   third-party-repo
 glibc               x86_64   ...   third-party-repo
# ★ 你只想装 some-new-tool,yum 却要顺手把 openssl、
#   glibc 这些【系统级关键库】给升级了!

# === ★ 这是怎么发生的 ===
# some-new-tool 来自一个第三方源,它依赖一个【更高
#   版本】的 openssl。yum 为了满足这条依赖,就会去
#   升级 openssl。
# ★ 而这个第三方源里的 openssl,可能和官方源的
#   版本线不一致 —— yum 一升,系统的 openssl 就被
#   换成了第三方源那个版本。

# === ★ 危害:一升级,一批旧程序集体遭殃 ===
# 系统上大量程序,都链接着原来那个版本的 openssl。
#   你把 openssl 一换:
#  - 运气好,新版兼容,相安无事;
#  - ★ 运气不好,某些程序要的旧版 libssl.so 没了
#    /符号变了 —— 一批服务,瞬间集体报 symbol not
#    found 或 cannot open shared object。
# ★ 本文系统上那个怪异的 libssl 版本,很可能就是
#   早先某次"yum 顺手升级"留下的 —— 第三方源把
#   openssl 改成了一个非主流版本。

# === ★ 防线 1:装之前,逐行看清 yum 要动什么 ===
# ★ yum 装东西前,会列出完整清单并停下来等你按 y。
#   ★ 别无脑回车!尤其盯紧"Updating""Updating for
#   dependencies"那几段 —— 看它有没有要动 glibc、
#   openssl、systemd 这种系统命脉。
$ yum install xxx --assumeno   # 只看它【打算】做什么,不真装
# ★ 发现它要升级关键库 —— 停,先搞清楚再说。

# === ★ 防线 2:给仓库设优先级(priorities)===
# 让【官方源】的优先级,高于第三方源。这样同一个
#   包,yum 优先用官方版,不会被第三方源抢走。
$ yum install yum-plugin-priorities
$ vi /etc/yum.repos.d/CentOS-Base.repo
[base]
...
priority=1                       # ★ 官方源,最高优先级
$ vi /etc/yum.repos.d/third-party.repo
[third-party]
...
priority=99                      # ★ 第三方源,优先级压低

# === ★ 防线 3:锁住关键包的版本(versionlock)===
# 把 glibc、openssl 这类"绝对不能被乱动"的包,锁死,
#   ★ 任何 yum 操作都不许升级/降级它们:
$ yum install yum-plugin-versionlock
$ yum versionlock add openssl openssl-libs glibc
$ yum versionlock list           # 看锁了哪些
# ★ 这之后,哪个第三方源想顺手升级 openssl,yum
#   都会被 versionlock 拦下。系统命脉,稳了。

# === ★ 防线 4:第三方源平时关掉,要用才开 ===
$ vi /etc/yum.repos.d/third-party.repo
enabled=0                        # ★ 平时禁用这个源
$ yum install xxx --enablerepo=third-party  # 用时临时开
# ★ 这样,日常 yum update 绝不会碰第三方源,只有
#   你明确指定时它才参与 —— 把"顺手升级"的口子堵死。

# === 认知 ===
# ★ 依赖问题除了"缺",还有"冲突":装第三方源的包,
#   yum 会为满足依赖顺手升级 openssl/glibc 等系统
#   关键库,可能让一批旧程序集体崩。防线:装前逐行
#   看 yum 清单、用 priorities 给官方源更高优先级、
#   versionlock 锁死关键包、第三方源平时禁用。

修复 6:rpm/yum 依赖排查纪律

# === 这次事故暴露的认知盲区,定几条纪律 ===

# === 1. ★ rpm 管单个包(查依赖不解依赖),yum 管整张依赖网(自动解析) ===

# === 2. ★ 装软件永远优先 yum,装本地 rpm 文件用 yum localinstall ===

# === 3. ★ 依赖写在包元数据里:rpm -qR 看 Requires,--provides 看 Provides ===

# === 4. ★ --nodeps 只跳过"检查"动作,丝毫不满足依赖,装出一运行就崩的半成品 ===

# === 5. ★ rpm -q 查得到 = 数据库里登记了,绝不等于运行时依赖都就位 ===

# === 6. 依赖缺失的正解是补齐:yum provides 反查 + 配好仓库,不是 --nodeps 绕过 ===
$ yum provides '*/缺失的库或文件'

# === 7. ★ 验证装好没,看 ldd 有没有 not found,而不只看 rpm -q ===
$ ldd /路径/可执行文件 | grep 'not found'

# === 8. ★ yum 安装清单里盯紧 Updating 段,别让第三方源顺手升级 glibc/openssl ===

# === 9. 关键库用 versionlock 锁死,第三方源设低 priority 或平时 enabled=0 ===

# === 10. 排查"rpm 装了却跑不起来"的步骤链 ===
$ rpm -q 包名                        # ① 数据库里在不在
$ rpm -qR 包名                       # ② 它需要哪些依赖
$ ldd 可执行文件 | grep 'not found'  # ③ 哪个库实际找不到
$ yum provides '*/那个库'            # ④ 哪个包能提供它
$ yum localinstall / yum install     # ⑤ 用 yum 正经补齐
# 按这个顺序,"装了却跑不起来"基本能定位、能根治。

命令速查

需求                        命令
=============================================================
查某个包装没装              rpm -q 包名
看一个包需要哪些依赖        rpm -qR 包名
看一个包提供哪些东西        rpm -q --provides 包名
反查谁提供某个库/文件       rpm -q --whatprovides '库名'
在仓库里找谁提供某东西      yum provides '*/库或文件'
正常安装(自动解依赖)      yum install 包名
装本地 rpm 文件(解依赖)   yum localinstall ./xxx.rpm
看可执行文件缺哪个库        ldd 可执行文件 | grep 'not found'
看系统有哪些共享库          ldconfig -p | grep 库名
只看 yum 打算做什么不执行   yum install xxx --assumeno
锁死一个包的版本            yum versionlock add 包名
临时启用某个源              yum install xxx --enablerepo=源名

口诀:rpm 管单包不解依赖,yum 管整张依赖网,装软件永远优先 yum
      --nodeps 只跳过检查不满足依赖,rpm -q 查得到不等于真能跑,装好要 ldd 验

避坑清单

  1. rpm 是底层工具只管单个包的安装查询卸载,它会检查依赖但不会自动解决依赖
  2. yum 是上层工具会解析整张依赖网自动下载所有需要的包并按序调 rpm 装上,装软件永远优先用 yum
  3. 依赖写在 rpm 包元数据里,Requires 列我需要什么 Provides 列我提供什么,yum 靠匹配这两者解析
  4. rpm -qR 看一个包需要什么,rpm --whatprovides 和 yum provides 反查谁能提供某个库或文件
  5. --nodeps 跳过的只是检查依赖这个动作,它丝毫没有满足依赖,缺的东西该缺还是缺
  6. rpm --nodeps 强装后数据库登记了 rpm -q 查得到,但依赖没就位是个一运行就崩的半成品
  7. 装好了是两件事数据库里在册加上运行时依赖真的都就位,rpm -q 查得到只代表前一件
  8. 依赖缺失的正解是补齐不是绕过,yum provides 反查后配好对应仓库让 yum 自己把依赖装全
  9. 装本地 rpm 文件要用 yum localinstall 它会自动解依赖,别用 rpm -ivh 它只装这一个文件
  10. yum 安装清单里盯紧 Updating 段别让第三方源顺手升级 glibc openssl,关键库用 versionlock 锁死

总结

这次"rpm 说装好了、程序却跑不起来"的事故,纠正了我一个关于"完成"的、藏得很深的错觉。在我过去的认知里,一件事"做完了",标志是【那个负责记录的系统,接受了它】。我装完软件,rpm -q 能查到它的名字和版本——在我心里,这就等于盖了章:名册上有它了,这事就【成了】。我信赖那份名册,就像信赖一张盖了红章的证书:证书在手,事情就办妥了。可这次,名册上明明白白写着"monitor-agent 已安装",那个程序却连一步都迈不动,倒在"找不到一个库"上。我一直当作铁证的那份名册,在现实面前,成了一张【它自己都兑现不了的空头支票】。现场逼着我把"装好了"这三个字,掰成了两半看。一半是【登记】——rpm 把文件拷进去,在数据库里记上一笔。这一半,--nodeps 帮我"顺利"地完成了。另一半是【就位】——这个程序真正要跑起来,它依赖的每一个库、每一个文件,都得实实在在地、正确地待在系统里。这一半,我从来没做,--nodeps 也根本不负责做。我过去一直以为,只要第一半成了,第二半会【自动】跟上——就像我以为,只要名册上记了你的名,你这个人就一定好端端地站在队列里。可 --nodeps 干的,恰恰是把这两半【硬生生劈开】:它让名册记下了一个,事实上缺胳膊少腿、根本站不起来的东西。我撕掉的那张"体检报告",不是让病好了,只是让我看不见病而已;而病,在那行 cannot open shared object 里,如约发作。复盘到根上我才明白,我混淆了"一个系统承认它"和"它本身是完整的"。rpm 数据库承认它,这是一种【行政事实】——名册的事;而它依赖齐全、真能运转,这是一种【物理事实】——它自己的事。--nodeps 的全部"魔力",不过是伪造了前一种事实,而对后一种,毫无触碰。我急着上线时,要的是"系统别再拦我",于是我用 --nodeps 买到了一个"不拦我"——可我真正需要的,从来是"这个程序能跑",而这两样,被我当成了一回事。这次最大的收获,是我对一切"它说已经好了"的回执,生出了一层警觉。一个接口返回了 200,不代表它背后那件事真的做成了;一个流程显示"已完成",不代表它该产生的结果真的产生了;一份名册上有了你的名字,不代表你真的具备了名字背后该有的一切。"被记录为完成"和"实质上完成",是两件需要分开确认的事——前者,是某个系统松了口、放了行;后者,要去摸那个东西本身,看它是不是真的立得住、转得动。所以下一次,当某个工具、某个系统告诉我"装好了""做完了""通过了",而我心里还没底时,我不会再满足于去查那份名册。我会绕到名册背后,去问那个最朴素的问题:把名册盖的章先放一边——这个东西,它【本身】,现在,真的能跑起来吗?因为让名册记下一笔,从来都太容易了;难的、也才是真正算数的,是让那个被记下的东西,自己站得稳、走得动。

—— 别看了 · 2026
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理 邮箱1846861578@qq.com。
Linux教程

服务器重启后 IP 没了:一次 Linux 网络运行时状态与持久化配置的复盘

2026-5-21 0:19:09

Linux教程

云盘扩容了 df 还是旧的:一次 Linux 磁盘分区与文件系统扩容的复盘

2026-5-21 0:27:30

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索