想象你要去一座陌生的城市旅行,每想买点东西都得满街乱转,找到店之后还要研究它什么时候补货、怎么退货、怎么验证是不是正品——如果每家店规则都不一样,你会崩溃。 安装软件也一样。每个操作系统就是一座城市,apt、yum、brew 是这三座城市里的“官方配送中心”:apt 是 Ubuntu 城的国营超市,yum 是 CentOS 城的批发仓库,brew 是 macOS 城的社区买手店。虽然招牌不同,但底层逻辑完全一致:查货架、下单、按配料单配齐依赖、送货上门、验货签收。 这篇文章就沿着“城市配送中心”这条主线,带你一次性搞懂三者的统一姿势——命令怎么记、源怎么换、依赖冲突怎么解、离线包怎么装、签名怎么验。学完之后,无论面前是哪座城市,你都能从容下单,不再抓瞎。

岗位关联

对 AI 从业者而言,模型训练和推理服务几乎都跑在 Linux 服务器上,配 CUDA、装编译依赖、部署推理引擎,全都绕不开 apt/yum。掌握这套统一姿势,等于给 AI 基建配了一把万能钥匙。

目录
  1. 可视化演示
  2. 包管理器初识
  3. apt常用命令
  4. yum仓库机制
  5. brew社区生态
  6. 镜像源加速
  7. 依赖与锁定
  8. 离线与安全
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

动态演示系统包管理apt/yum/b的核心机制,通过输入/处理/存储/输出四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

系统包管理apt/yum/b:sapt s1: apt/yum/bre s2: 软件包查询安装更新与卸 核心机制可视化 系统包管理apt/yum/b整体架构与关键组件

包管理器初识

在配送中心出现之前,装软件就像“手工去工厂提货”:上网找到源码压缩包,下载到本地,敲 ./configure && make && make install 手动编译安装。库版本差一点、编译器缺个参数,立刻报错。就好比你为做一顿饭,要专程去东北买面粉、去海南买椰子,每个产地还各说各的方言。

于是每座操作系统城市都建起了自己的配送中心——包管理器。它的职责是统一的:把软件打包成标准集装箱(软件包),替你查货架(搜索)、按配料单配齐原料(解析依赖)、送货上门(安装落盘)、定期补货(升级),不满意还能退货(卸载)。

一个软件包通常由三部分组成:可执行程序本体、描述版本/作者/依赖关系的元信息,以及安装卸载时要执行的脚本。apt 的 .deb、yum 的 .rpm、brew 的 bottle 都是集装箱的不同规格,只要学会一家,另外两家只是换了个下单话术而已。

记住这个集装箱模型,后面所有章节其实都在讲同一件事:配送中心如何把集装箱放到你的系统里,同时按配料单把依赖一起配齐。apt、yum、brew,不过是三家门店的不同叫法。

Package(p)={程序(p), 元信息(p), 依赖清单(p)}\displaystyle \text{Package}(p) = \{ \text{程序}(p),\ \text{元信息}(p),\ \text{依赖清单}(p) \}
这个公式是说:一个软件包就像一个大集装箱,里面装着“可运行的程序”“标签(元信息)”和“配料表(依赖清单)”三类货物。
  1. Package(p)表示名为 p 的软件包整体,它像一个标准集装箱,把散乱的部件整合成一件可配送的货物。
    Package(p)\displaystyle \text{Package}(p)
  2. 程序(p)集装箱里的主体货物,也就是编译好的可执行文件本体,装入系统后直接可运行。
    程序(p)\displaystyle \text{程序}(p)
  3. 元信息(p)集装箱外贴的标签,记录版本号、作者、协议等描述性数据,帮配送中心识别货物。
    元信息(p)={版本,作者,协议}\displaystyle \text{元信息}(p) = \{ \text{版本}, \text{作者}, \text{协议} \}
  4. 依赖清单(p)像食品配料表,列出安装前必须备齐的其他软件包,是配送中心配货的依据。
    依赖清单(p)={d1,d2,…,dk}\displaystyle \text{依赖清单}(p) = \{ d_1, d_2, \ldots, d_k \}

apt常用命令

Ubuntu 和 Debian 城里的“国营超市”叫 apt。它的招牌货架叫做“源”(sources),每行配置对应一个上游仓库。超市的规矩是:下单前先看货架标签——所以第一步永远是刷新货架信息,而不是直接冲进去拿货。

apt update 并不是升级软件,而是刷新本地货架索引;真正把旧款换成新款的是 apt upgrade。接下来就是熟悉的流程:apt install nginx 下单、apt remove nginx 退货、apt search nginx 查货架、apt list --installed 翻自家库存。装完的软件统一落盘到系统目录,配送中心自动记录台账。

源配置文件在 /etc/apt/sources.list 及 /etc/apt/sources.list.d/ 目录下,每行形如 deb <URL> <套件名> <组件>。它相当于告诉超市:去哪个仓库、进哪批货、开放哪些货架。apt install 时,配送中心会顺着这份配置,把主包和依赖一起从源里拉回来。

记住“先 update 后 install,就像逛超市先看入口处的新货公告栏”。忘了 update 就 install,常常会提示“找不到这个包”——不是店里没货,而是你手里的标签页太旧了。

本地索引=⋃i=1n源i  →  apt  update    可搜索货架清单\displaystyle \text{本地索引} = \bigcup_{i=1}^{n} \text{源}_i \;\xrightarrow{\;apt\;update\;}\; \text{可搜索货架清单}
意思是:apt update 把 n 个软件源的货架信息合并成一张本地大清单,之后 search 和 install 才能在这张清单上快速查找。
  1. 源_i第 i 个软件源,相当于配送中心签约的一个供货仓库,货架源头。
    源i\displaystyle \text{源}_i
  2. 并集 ∪把所有源中的软件包合并成一张大清单,保证不遗漏任何货架上的商品。
    ⋃i=1n\displaystyle \bigcup_{i=1}^{n}
  3. apt update执行刷新动作,把远程货架同步成本地索引,刷新后 search 才能搜到新包。
    →  apt  update  \displaystyle \xrightarrow{\;apt\;update\;}

yum仓库机制

CentOS、RHEL 这类服务器之城没有老牌国营超市,取而代之的是面向企业的大宗批发仓库 yum。它把供货合同统一放在 /etc/yum.repos.d/ 目录下,每个 .repo 文件就是一份合同。

一份 repo 合同有四个关键字段:name 仓库名、baseurl 仓库地址、enabled 是否启用、gpgcheck 是否验签。yum 配送的是 .rpm 集装箱,命令 yum install、yum remove、yum list 与 apt 几乎一一对应。同族的新一代叫 dnf,命令几乎一致,可以当成同一套话术的升级版。

批发市场的特色是“组包”:yum groupinstall "Development Tools" 一条命令下单几十个包,适合初始化一台新服务器。但 yum 的依赖解析也曾被称为“依赖地狱”,于是社区维护了 EPEL(Extra Packages for Enterprise Linux),相当于给企业仓库额外租了几排社区货架。装新软件之前,先 yum install epel-release 把这排货架激活。

所以当 yum 提示缺依赖时,别急着怀疑合同本身,先跑 yum repolist 确认几个仓库真的启用了——就像批发商进货前,先清点一遍合作中的供货渠道。

可安装(p)  ⟺  ⋀d∈deps(p)(d∈R1∪R2∪⋯∪Rk)\displaystyle \text{可安装}(p) \iff \bigwedge_{d \in \text{deps}(p)} \left( d \in \mathcal{R}_1 \cup \mathcal{R}_2 \cup \cdots \cup \mathcal{R}_k \right)
意思是:软件包 p 能被安装,当且仅当 p 的每一个依赖,都能在至少一个已启用的仓库里找到货源。
  1. deps(p)软件包 p 的依赖集合,相当于这张商品的配料单。
    deps(p)\displaystyle \text{deps}(p)
  2. 每个依赖都要满足逻辑与 ∧ 表示所有配料缺一不可,任何一个依赖缺失,安装都要失败。
    ⋀d∈deps(p)\displaystyle \bigwedge_{d \in \text{deps}(p)}
  3. 仓库并集一个依赖只要出现在任意一个已启用仓库中即可,并不要求所有仓库都备货。
    R1∪R2∪⋯∪Rk\displaystyle \mathcal{R}_1 \cup \mathcal{R}_2 \cup \cdots \cup \mathcal{R}_k

brew社区生态

macOS 城没有官方配送中心,程序员们干脆自己开了一家社区买手店 Homebrew,招牌缩写 brew。它的规矩是“客人东西别乱放”:默认把软件安装进 /usr/local 或 /opt/homebrew,与系统自带的软件互不干扰,卸载也干净。

每个软件对应一个“配方”(formula),是一段 Ruby 脚本,写清楚从哪里下载、怎么编译、装进哪个 Cellar(酒窖/主目录)。brew install nginx 就是按配方配一坛酒;第三方维护的配方集合叫 tap,相当于给买手店额外租的货架,brew tap homebrew/cask 就是签约一个新货架。

brew 和另两家的最大区别是“上新快”:官方配送中心走完质检流程要好几个月,社区买手店以天甚至小时为单位上架新品,特别适合装最新版开发工具。brew install --cask wechat 装的是图形界面应用(cask 相当于瓶装成品酒),brew services start nginx 还能把软件注册成开机自启服务——让买手店顺便负责长期保鲜配送。

买手店的优点是上新快、货多,代价是没有官方质保。装完若提示 brew doctor 有问题,乖乖跑一遍体检——社区店的货虽然新鲜,也得自己确认配料没有相冲。

brew install f  ≡  formula(f)→bottle(f)→Cellar(f)\displaystyle \text{brew install } f \;\equiv\; \text{formula}(f) \to \text{bottle}(f) \to \text{Cellar}(f)
意思是:用 brew 安装软件 f,就是拿配方(formula)找到预编译好的瓶装产物(bottle),再把它倒进 brew 的仓库(Cellar)里。
  1. formula(f)软件 f 的安装配方脚本,描述原料来源和制作工艺。
    formula(f)\displaystyle \text{formula}(f)
  2. bottle(f)预编译好的瓶装产物,多数情况直接使用,不必现场“酿酒”(编译)。
    bottle(f)\displaystyle \text{bottle}(f)
  3. Cellar(f)brew 的安装主目录,相当于买手店的仓库,按配方名分格存放成品。
    Cellar(f)\displaystyle \text{Cellar}(f)

镜像源加速

官方货架通常远在海外,配送要绕地球一圈。国内镜像源就是建在你家门口的分拣站——清华 TUNA、阿里云、中科大等团队把官方仓库完整复制一份到国内服务器。你只要换一下下单地址,速度立刻从海运变成同城闪送。

给 apt 换源,就是重写 /etc/apt/sources.list,把域名改成镜像地址,然后关键一步 apt update 刷新索引。给 yum 换源,把 .repo 文件里的 baseurl 改成 mirrors.aliyun.com 对应路径。给 brew 换源,先设置环境变量 HOMEBREW_BOTTLE_DOMAIN 指向清华 bottle 镜像,再 brew update 刷新配方。

请记住:下载快不等于天然可信。镜像团队承诺内容与官方逐字节一致,但你仍应保留 gpgcheck=1,让配送箱上的防伪码说了算。另外换源后若不刷新缓存,索引还是旧的,就像地图没更新,分拣站建好了你也导航不到。

一句话:镜像源解决“远”的问题,验签解决“假”的问题,两者搭配才最安心。换完源记得执行 apt update / yum makecache / brew update,让分拣站正式开业。

耗时=∑isizeibandwidthi  ⇒  最优源=arg⁡min⁡m∈Mdist(m)\displaystyle \text{耗时} = \sum_{i} \frac{\text{size}_i}{\text{bandwidth}_i} \;\Rightarrow\; \text{最优源} = \arg\min_{m \in \mathcal{M}} \text{dist}(m)
意思是:一次安装的总耗时等于每个软件包体积除以网速的累加,想省时间,就在所有镜像源里选离你最近的那个。
  1. size_i / bandwidth_i每个软件包的体积除以本机到源节点的带宽,即理想传输耗时的估算。
    sizeibandwidthi\displaystyle \frac{\text{size}_i}{\text{bandwidth}_i}
  2. 求和 Σ把所有包的传输时间累加起来,得到一次完整安装的总耗时。
    ∑i\displaystyle \sum_{i}
  3. argmin dist(m)在镜像源集合中挑选距离最近、延迟最低的那个,即全局最优解。
    arg⁡min⁡m∈Mdist(m)\displaystyle \arg\min_{m \in \mathcal{M}} \text{dist}(m)

依赖与锁定

配货时最头疼的场景:你要 A 面包,它需要面粉和黄油;B 面包也用同一袋面粉,但 B 要求面粉必须是 2.0 版,A 却锁定 1.5 版——这就是“依赖冲突”。配送中心的搭货系统会自动算出每件货的配料单,把缺的原料一起拉进配送车,理论上你只需下一个单。

理论很完美,实践却常需人为干预。当你不希望某个包被升级弄坏环境,就要“版本锁定”。三者各有一招:apt 用 apt hold <包名> 按住不放,yum 用 yum versionlock <包名> 锁进保险柜,brew 用 brew pin <包名> 用图钉钉住。解锁分别是 apt unhold、yum versionlock clear、brew unpin。

遇到顽固冲突,配送中心的建议有三条:第一,锁定低版本母包,升级配套依赖,例如 apt hold libssl 后重装相关软件;第二,用容器隔离冲突环境——Docker 相当于给每道菜配一间独立厨房,锅碗瓢盆互不借用;第三,换镜像源里的兼容版本重新构建。最忌讳的是 --force 硬装,强令发货的结果往往是连带砸坏更多货架。

锁定就像给货架上的老物件贴上“此款已绝版,请勿更换”的标签。但要记住,锁定只是缓兵之计,真正的解法是让所有依赖版本达成共识——要么整体升级,要么容器隔离,要么换一条兼容轨道。

锁定(v): vinstalled⪰vrepo  ∧  hold(v)=1\displaystyle \text{锁定}(v):\ v_{\text{installed}} \succeq v_{\text{repo}} \;\wedge\; \text{hold}(v) = 1
意思是:版本锁定就是让系统里已装版本“不再追新”,同时给这个包打上“禁止升级”标记,包管理器在升级时会自动跳过它。
  1. v_installed系统里当前已安装的版本号,代表现状。
    vinstalled\displaystyle v_{\text{installed}}
  2. v_repo仓库里可升级到的最新版本号,代表诱惑。
    vrepo\displaystyle v_{\text{repo}}
  3. hold(v)=1锁定标记为真,包管理器在 upgrade 时会自动跳过这个软件包。
    hold(v)=1\displaystyle \text{hold}(v) = 1

离线与安全

有些生产机房的网络是隔离的,配送车进不来。这时你需要“冷链车”:先在能上网的环境把 .deb / .rpm / bottle 安装文件下载到移动介质,再进隔离区手动发货。apt 系用 dpkg -i xxx.deb,yum 系用 rpm -ivh xxx.rpm。和在线安装不同,离线装不查货架,依赖要自己提前备齐,否则直接报“缺料”。

离线少了配送中心的验身环节,安全问题更要靠防伪码——GPG 签名。每个官方仓库都持有自己的密钥对,签名相当于软件包出厂时的防伪溯源码;包管理器用仓库方提供的公钥验证,对不上就拒绝收货。yum 的 repo 里写 gpgcheck=1 就是强制验签开关,apt 通过 sources.list 里的 [signed-by=...] 指定公钥,brew 则用 shasum 校验下载摘要。

信任不是凭空来的,而是一条链:你信任发行版厂商,厂商的公钥被内置在安装镜像里,仓库签名用这把公钥生成。只要链条不破,镜像源再怎么加速搬运,内容都无法被篡改。攻击者就算把你的下载源劫持到钓鱼仓库,也会因为验签不过而颗粒无收。

离线安装就像接收冷链包裹:东西本身是放心的,但你要亲自对防伪码。企业运维的黄金准则是“宁可装不上,不可装错包”——签名对不上,果断丢弃。

信任(p)  ⟺  Verifypub(p)=1  ∧  gpgcheck(p)=1\displaystyle \text{信任}(p) \iff \text{Verify}_{\text{pub}}(p) = 1 \;\wedge\; \text{gpgcheck}(p) = 1
意思是:一个软件包要被信任,必须同时满足两个条件——公钥验签通过,且仓库开启了强制验签开关。
  1. Verify_pub(p)用仓库公钥对软件包 p 的签名做验证,签名与内容匹配则结果等于 1。
    Verifypub(p)=1\displaystyle \text{Verify}_{\text{pub}}(p) = 1
  2. gpgcheck(p)仓库配置中是否强制验签,1 表示开启,0 表示关闭。
    gpgcheck(p)=1\displaystyle \text{gpgcheck}(p) = 1
  3. 逻辑与 ∧两个条件必须同时成立,缺一个都不接受安装。
    ∧\displaystyle \wedge

AI 应用场景

场景1:GPU训练机的系统依赖环境搭建

阶段:环境准备 / 基础设施搭建

解决的问题:AI 工程师拿到一台新的 Ubuntu GPU 服务器,要装 NVIDIA 驱动、CUDA、编译工具链。直接源码编译慢且容易因缺库反复报错;用 apt install 一条命令就能把 nvidia-driver、cmake、ninja、gcc 连同依赖按“配料单”配齐。需要固定驱动版本时,用 apt hold 锁定,防止某次 upgrade 把驱动升级崩坏。

具体案例:某算法团队为 8 卡 A100 服务器搭建 PyTorch 训练环境:先 apt update 刷新索引,再 apt install 系统级依赖,核心库用 apt hold 锁版本,再用 conda 装 Python 层依赖,整个集群两天内交付。

场景2:生产环境推理服务的依赖锁定

阶段:模型部署 / 运维保障

解决的问题:推理服务(如 vLLM、Triton)依赖 nginx、redis、opengl 等系统库,生产环境最怕“无人值守的深夜自动升级把依赖换掉”。yum 的 versionlock 可以把关键 rpm 锁死版本;镜像源加速则让上百台机器同时拉包不卡顿。

具体案例:某公司在 CentOS 集群部署 Stable Diffusion 推理服务,用 yum groupinstall 装基础工具组,用 yum versionlock 锁死 libstdc++ 等核心运行库,再配合阿里云镜像源批量交付,回滚率降为零。

场景3:Docker镜像里装系统依赖

阶段:开发 / 镜像构建

解决的问题:AI 工程师写 Dockerfile 时,基础镜像一启动就要用 apt 装系统库。此时 apt 是“一次性配送中心”,配完货就销毁,镜像既快又干净。

具体案例:一个 OCR 项目的 Dockerfile 中,RUN apt-get update && apt-get install -y libgl1 libglib2.0-0 解决 OpenCV 的底层依赖,最后 rm -rf /var/lib/apt/lists/* 清掉索引,镜像体积减少约 30%。

Python 演示

python40 行
#!/usr/bin/env python3"""mini_pkg.py: 极简包管理器模拟器, 演示依赖解析与安装流程"""import hashlib REPO = {    "nginx":   {"depends": ["openssl", "zlib", "pcre"], "ver": "1.24.0"},    "openssl": {"depends": [], "ver": "3.0.8"},    "zlib":    {"depends": [], "ver": "1.3"},    "pcre":    {"depends": [], "ver": "8.45"},} INSTALLED = {} def resolve(name, visiting):    if name in INSTALLED:        return []    if name not in REPO:        raise RuntimeError("仓库中找不到软件包: " + name)    if name in visiting:        raise RuntimeError("发现循环依赖: " + name)    visiting.add(name)    plan = []    for dep in REPO[name]["depends"]:        plan.extend(resolve(dep, visiting))    visiting.remove(name)    plan.append(name)    return plan def install(name):    plan = resolve(name, set())    for pkg in plan:        meta = REPO[pkg]        digest = hashlib.sha256(pkg.encode()).hexdigest()[:8]        INSTALLED[pkg] = {"ver": meta["ver"], "checksum": digest}        print("[安装] %s-%s 校验=%s" % (pkg, meta["ver"], digest)) if __name__ == "__main__":    install("nginx")    print("当前已安装: " + ", ".join(sorted(INSTALLED)))    print("总共安装 %d 个软件包" % len(INSTALLED))
目的:用 30 行代码模拟一个迷你包管理器,展示依赖解析、循环检测和“安装校验”三步核心流程,帮你直观理解 apt/yum 内部在做什么。
  1. REPO = {模拟配送中心的货架数据,每个软件记录依赖和版本
  2. def resolve(name, visiting):递归解析依赖的核心入口,相当于按配料单配货
  3. plan.extend(resolve(dep, visiting))深度优先遍历,让子依赖永远排在父包之前安装
  4. raise RuntimeError("发现循环依赖: " + name)检测到 A 依赖 B、B 又依赖 A 时立即报错,防止死循环
  5. digest = hashlib.sha256(pkg.encode()).hexdigest()[:8]模拟 GPG 防伪校验,为每个包生成短校验码
  6. INSTALLED[pkg] = {"ver": meta["ver"], "checksum": digest}模拟安装落盘并登记台账
  7. print("[安装] %s-%s 校验=%s" % (pkg, meta["ver"], digest))打印安装日志,与实际包管理器的输出风格一致

常见误区

误区刚用 Linux 时看到 update 就以为是升级,跑完 `apt update` 后还奇怪为什么软件版本一个都没变。

正解update 只做一件事——刷新软件源索引,相当于超市更新货架标签。真正升级软件要靠 apt upgrade。正确流程是“先 update 拿到新货单,再 upgrade 按货单补货”,两步缺一不可。yum 对应 makecache,brew 对应 brew update,都是先刷标签再补货。

为何常见:英文 update 和 upgrade 日常都翻译成“更新”,初学者自然混淆;加上很多教程只说“先 update”,让人误以为它已经完成了全部工作。

误区反正都是装软件,apt 装一份、brew 再装一份,双保险肯定更稳妥。

正解同一软件装两遍会造成双份二进制、两个版本、两处路径,PATH 里谁在前谁生效,后患无穷。系统级工具交给 apt,个人开发工具交给 brew,别用两家配送中心买同一件商品。

为何常见:用户在不同教程里分别看到“用 apt 装”和“用 brew 装”,照单全收,忽略了两种包管理器各自管辖的目录体系。

误区把 sources.list 改成清华源后马上 `apt install`,却感觉没变快,甚至报错。

正解换源只是改了“下单地址”,本地索引还是旧地图。必须再执行 apt update 让索引从新源重新拉取;yum 换 baseurl 后要 yum makecache,brew 换域后要 brew update。只有刷新完缓存,新的分拣站才算正式开业。

为何常见:生活里改收货地址是立即生效的,但包管理器的索引是本地缓存快照,不会自己感知源的变化。

误区`apt remove nginx` 之后,nginx 依赖的 openssl 应该也一起删掉吧?磁盘怎么还是满的。

正解remove 很保守,卸载时只删主包,不敢动“别人可能还在用”的依赖。清理孤儿依赖需要显式执行 apt autoremove,yum 对应 yum autoremove,brew 对应 brew autoremove。配送中心只清理确认无人使用的配料,避免误伤。

为何常见:人们按“购物退货”的直觉理解卸载,但配送中心无法预知其他程序是否还依赖这些库,只能先保留。

面试题

Q1. apt update 命令的主要作用是什么?

单选题 · easy

  • A.升级所有的系统软件
  • B.刷新软件包索引列表← 正确答案
  • C.卸载无用的依赖包
  • D.重启系统全部服务

答案:B。update 只刷新“货架标签”即本地索引,不升级任何软件,真正升级是 upgrade 的职责。A 说的是 upgrade,C 是 autoremove 的活,D 是服务管理工具的工作。

Q2. 下列哪个是 Red Hat 系的包管理器?

单选题 · easy

  • A.apt, 使用 deb 包格式
  • B.yum, 使用 rpm 包格式← 正确答案
  • C.brew, 使用 bottle 格式
  • D.pip, 使用 wheel 格式

答案:B。Red Hat 系(CentOS/RHEL/Fedora)使用 rpm 包格式,包管理器是 yum(新版为 dnf)。apt 属于 Debian/Ubuntu 系,brew 属于 macOS 社区,pip 管理 Python 包,三者都不是 Red Hat 系的答案。

Q3. /etc/apt/sources.list 里配置的是什么?

单选题 · easy

  • A.记录已装软件的黑名单
  • B.配置 apt 的下载源地址← 正确答案
  • C.指定系统日志输出位置
  • D.存放全部签名公钥文件

答案:B。sources.list 是 apt 的“供货合同”,告诉包管理器去哪里下载软件包。它不记录已装软件(那是 dpkg 状态库),不配置日志(那是 rsyslog),不存放公钥(那是 keyrings 目录)。

Q4. brew cask 这个子命令专门用来安装什么?

单选题 · mid

  • A.命令行工具型软件
  • B.带图形界面的应用← 正确答案
  • C.系统的内核驱动程序
  • D.编程语言的解释器

答案:B。cask 在 brew 里指“瓶装成品”,对应带 GUI 的桌面应用。formula 才是命令行工具,内核驱动和解释器都不是 cask 的定位。这就像买手店里,散装酒(formula)和瓶装酒(cask)分属不同货架。

Q5. 想让 apt 不再升级某个重要库,应该使用哪个命令?

单选题 · mid

  • A.apt hold 该库包名← 正确答案
  • B.apt free 该库包名
  • C.apt stop 该库包名
  • D.apt deny 该库包名

答案:A。apt hold 就是“按住不放”,给包打上禁止升级的标记。free、stop、deny 都不是 apt 的命令。yum 对应 versionlock,brew 对应 pin,三者是不同配送中心对“贴绝版标签”的不同叫法。

Q6. 更换国内镜像源之后,紧接着必须执行哪一步?

单选题 · mid

  • A.重新编译整个系统内核
  • B.刷新本地软件包索引← 正确答案
  • C.删除掉全部旧软件
  • D.重启服务器网络服务

答案:B。换源只是改下单地址,本地索引还是旧地图。必须 apt update / yum makecache / brew update 刷新缓存,新源才生效。编译内核、删软件、重启网络都与换源无直接关系。

Q7. rpm 离线安装时提示缺少依赖,正确的处理方式是什么?

单选题 · hard

  • A.手动下载依赖一起安装← 正确答案
  • B.用 --nodeps 强行跳过检查
  • C.关闭防火墙后重新尝试
  • D.把 rpm 改名成 deb 再装

答案:A。离线安装没有配送中心自动配货,必须自己把依赖集齐后按顺序安装。--nodeps 强行跳过检查会造成运行时崩溃,关闭防火墙不解决缺料问题,改扩展名更是无效操作。

Q8. 下列哪些属于安全的依赖清理方式?

多选题 · hard

  • A.使用 apt autoremove 清理← 正确答案
  • B.使用 brew autoremove 清理← 正确答案
  • C.删除 /usr/lib 下全部文件
  • D.使用 yum autoremove 清理← 正确答案

答案:ABD。autoremove 是配送中心安全回收“确认无人使用的配料”,三家都有对应命令。C 是灾难性操作,/usr/lib 里除了孤儿依赖还有大量系统运行库,全删会导致系统瘫痪,和卸软件完全是两回事。

Q9. 下列哪些方式属于离线安装可用方案?

多选题 · mid

  • A.用 dpkg -i 装 deb 包← 正确答案
  • B.用 rpm -ivh 装 rpm 包← 正确答案
  • C.用 brew 命令装 cask 应用
  • D.离线安装下载好的 bottle← 正确答案

答案:ABD。dpkg -i 和 rpm -ivh 是典型的离线安装命令,bottle 也可以先下载再离线放置。而 brew install --cask 必须连接仓库现场配货,隔离网络中无法完成,相当于冷链车开不进断桥。

Q10. 依赖冲突时,合理的处置策略有哪些?

多选题 · hard

  • A.锁定版本同时升级配套包← 正确答案
  • B.引入容器隔离冲突环境← 正确答案
  • C.强制安装并覆盖所有文件
  • D.更换兼容的源重新构建← 正确答案

答案:ABD。锁定母包版本并升级配套包,能让各方依赖达成共识;容器隔离相当于给每个应用配独立厨房;换兼容源重新构建是从源头解决。C 是典型的暴力硬装,会破坏配送台账,酿成更多冲突。