拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Linux Day14——软件包管理apt

Linux Day14——软件包管理apt

---

type: learning-note

title: Linux:软件包管理 apt——装 / 卸 / 查

date: 2026-09-29

description: apt 是什么、update 刷的是"货单"不是软件、apt 与 dpkg 的两层关系、dpkg -l 状态位 ii/rc、search 与 show、交易预览三组、./ 的作用、remove 与 purge、autoremove 清孤儿

---

# 2026-09-29 学习笔记

> 📌 GitHub:https://github.com/AR-firefly

## 笔记区

### 核心观点

**apt 是 Ubuntu 的软件包管理命令**

`apt --help` 原文:_apt is a commandline package manager and provides commands for searching and managing as well as querying information about packages._

「apt 就是可以搜看装删更新的指令」但「更新」在 apt 里是**两个动作**,`update` 动的是**货单**,`upgrade` 才动**软件**。

**`apt update` 刷的是"货单",不是软件**

- **仓库(repository)**:网上放软件的地方。本机配了 **2 个**(`archive.ubuntu.com` + `security.ubuntu.com`),写在 `/etc/apt/sources.list.d/ubuntu.sources`。⚠️ `/etc/apt/sources.list` **不保证是全量**(本机它只剩注释)。

- **索引(货单)**:仓库发布的"里面有哪些包、什么版本"的清单。`apt update` 把它拷到本地 `/var/lib/apt/lists/`——本机 **65 个文件、150M**。

- 拷完 apt 顺手对一遍账,报"**55 packages can be upgraded**",**但一个都没升**。

- `man apt` 原文:_update is used to **download package information** from all configured sources._

**屏幕上那 4 行 `Hit` 是哪来的**:配置文件里 `archive` 那段写了 **3 条** `Suites`(`resolute` / `-updates` / `-backports`)、`security` 那段写了 **1 条**(`resolute-security`)——**3 + 1 = 4**。不是随便冒出来的。

**`apt list` 与 `apt list --installed` 是两个世界**

| 命令 | 条数 | 列的是 |

| ---------------------- | --------- | -------------------- |

| `apt list` | **78416** | 仓库里**全部能装的** |

| `apt list --installed` | **545** | **本机已装的** |

`--installed` 是个**过滤条件**——选项就是"命令后面的开关",加一道筛子就换一种结果。

**`apt` 和 `dpkg` 是两层,不是上下级**

- **`dpkg` 在下层**:`dpkg --help` 里 `-i|--install` 后面跟的是 `<.deb file name>`——**它只认本地 `.deb` 文件**,不上网、不算依赖、不下载。

- **`apt` 在上层**:上网搬索引 → 算依赖 → 把 `.deb` 下到本地 → **交给 dpkg 装**(装包时预览里的 `Inst` ↔ dpkg 的 `--unpack`、`Conf` ↔ `--configure`)。

- **站在上层 = 上下都能看**:apt 往外看得到仓库,**往下也读得到本机那本账**(`/var/lib/dpkg/status`,本机 **544** 个包,跟 `apt list --installed` 的 545 对得上)。

- ⚠️ 所以**不是**"apt 管网上、dpkg 管本机"——**"本机装了什么",两个都看得到**。

**`dpkg -l` 的三个状态位**

表头那三行是**指针**:`+` 在第几位,那一行就解释第几位。

| 位 | 名字 | 在问什么 |

| --- | ----------- | --------------------------------- |

| 1 | **Desired** | 你**希望**它怎样(U/I/R/P/H) |

| 2 | **Status** | **实际**怎样(N/I/C/U/…) |

| 3 | **Err** | 有没有坏(**出现大写字母 = 坏**) |

- **`ii`** = 期望装 + 已装 + 无错 ← 正常已装的样子

- **`rc`** = **r**emove + **c**onffiles remain ← **包卸了、配置文件还在**

**`search` 搜的是描述,`show` 给的是身份**

- `search` 在**包的描述**里搜(`apt --help`:_search in package descriptions_)。所以搜 `figlet` 出来 **9 个包**,真叫 figlet 的只有 1 个——`toilet` 能冒出来,是因为它描述里写着 "similar to **FIGlet**"。

- `show` 给完整字段:`Version` / `Installed-Size`(装完占多少)/ `Depends`(依赖谁)/ `Download-Size`(下多少)/ `APT-Sources`(从哪个仓库哪条线来)。

**装包前那张纸:三样 + 三组**

三样最该看:**装哪些包 / `Download size` / `Space needed`**。(卸的时候对应的是 `Freed space`,一进一出。)

三组按「**谁点的名**」分:

```

Installing: ← 你点名的

Installing dependencies: ← apt 为满足依赖自己算出来带上的(**必需,不是次要**)

Suggested packages: ← 只是建议,**apt 从不自动装**

```

⚠️ `Installing dependencies` 那组不是"次要"——本机实测:想单独卸掉 `libcaca0`,apt 要**把 toilet 一起删掉**(没它 toilet 跑不起来)。

**`./` 的作用**

apt 默认把参数当**仓库里的包名**。`./` 是**路径前缀**,告诉它"这是当前目录下的文件"。

| 写法 | apt 当作 | 结果 |

| ------------------------------ | ------------ | ----------------------------------------------------------------------- |

| `figlet_2.2.5-3.1_amd64.deb` | 仓库里的包名 | `Error: Unable to locate package ...` |

| `./figlet_2.2.5-3.1_amd64.deb` | 本地文件路径 | `Note, selecting 'figlet' instead of './...'`——**打开文件、读出真包名** |

「`./` 是从本地找」。

**`remove` 与 `purge`**

| | 程序文件 | 配置文件 | `dpkg -l` 那行 |

| -------- | -------- | -------- | -------------- |

| `remove` | 删 | **留** | 变 **`rc`** |

| `purge` | 删 | **删** | **整个消失** |

`man dpkg` 原文(`-r, --remove`):_This removes everything **except conffiles** ... **which may avoid having to reconfigure the package if it is reinstalled later**._

**这就是"为什么 remove 要故意留着配置"的官方答案**:以后重装同一个包,改过的设置还在。

`man apt-get` 原文(purge):_identical to remove except that packages are removed and purged (**any configuration files are deleted too**)._

**`autoremove` 清孤儿**

- **孤儿包** = 当初作为依赖**自动装上**(就是点 3 那个 `[installed,automatic]` 标记)、现在**没有任何包再用它**

- `remove toilet` 时 apt 自己会说:_The following packages were automatically installed and are no longer required_ —— **但它不动手**,把决定权留给人

- 判断跟"装多久""仓库里有没有"都**无关**,只看**本机的依赖关系**

### 关键方法/流程

- **刷货单**:`sudo apt update`

- **搜 → 看详情**:`apt search 关键词` → `apt show 包名`

- **看装了哪些**:`apt list --installed`(apt 口径)/ `dpkg -l`(dpkg 口径,带状态位)

- **装**:`sudo apt install 包名`(**先看那张纸的三样**)

- **装本地 deb**:`sudo apt install ./xxx.deb`(`./` 不能省)

- **卸**:`sudo apt remove 包名`(留配置)/ `sudo apt purge 包名`(连配置删)

- **清孤儿**:`apt autoremove --dry-run`(先看)→ `sudo apt autoremove`

- **只演示不动手**:`-s` = `--dry-run` = `--just-print` = `--no-act`(`man apt-get` 里是同一串别名)

- **查操作历史**:`/var/log/apt/history.log`(记着**发起人** `Requested-By`)

### 实战记录

**① 装 figlet —— 那张纸的三样**

```

Installing: 1

Download size: 138 kB

Space needed: 752 kB / 1024 GB available

```

**② remove → purge 的四个证据**

```

装完 ii figlet ... /etc/emacs/site-start.d/50figlet.el 在(290 字节)

remove 之后 rc figlet ... 文件还在(290 字节,日期没变)

purge 之后 那一行整个消失 ls: No such file or directory

```

**③ toilet 带出两个依赖,卸完变孤儿**(用户亲手做)

```

Installing: 3

Installing dependencies:

libcaca0 toilet-fonts

(remove toilet 之后 apt 自己提示)

The following packages were automatically installed and are no longer required:

libcaca0 toilet-fonts

```

---

## 线索区(学完后合上材料,自问自答)

**Q: `apt update` 下载的是什么?它升级软件吗?**

A: 下载的是**索引(货单)**——"仓库里有哪些包、什么版本"。**它不升级任何软件**,只把货单拷到本地(`/var/lib/apt/lists/`),升软件是 `apt upgrade`。

**Q: 为什么 `apt update` 和 `apt upgrade` 必须分两步?**

A: apt 做任何决定都得先有货单,货单是旧的就只能算出旧结果。**先刷货单,再照着货单动手。**

**Q: `apt list` 和 `apt list --installed` 差在哪?**

A: `--installed` 是个**过滤条件**。不带 → **78416** 条(仓库里全部);带了 → **545** 条(本机已装)。

**Q: `apt` 和 `dpkg` 是什么关系?"本机装了什么"谁看得到?**

A: **两层分工**:`dpkg` 在下层,**只认本地 `.deb`**、不上网不算依赖;`apt` 在上层,上网、算依赖、下载,**再交给 dpkg 装**。**本机装了什么,两个都看得到**(apt 在上层,往下读得到 dpkg 那本账)。

**Q: `dpkg -l` 那三个状态位分别在问什么?**

A: 第 1 位 **Desired**(你希望它怎样)· 第 2 位 **Status**(实际怎样)· 第 3 位 **Err**(有没有坏,大写字母 = 坏)。

**Q: `ii` 和 `rc` 分别是什么意思?**

A: `ii` = 期望装 + 已装 + 无错。`rc` = **r**emove + **c**onffiles remain——**包卸了、配置文件还在**。

**Q: 装包前那张纸,哪三样最该看?**

A: **装哪些包 / `Download size`(下多少)/ `Space needed`(占多少)**。不看就回车 = 放弃唯一一次说"不"的机会。

**Q: 预览里 `Installing` / `Installing dependencies` / `Suggested` 凭什么分?**

A: 按**谁点的名**。第一组你点的;第二组 apt 为满足依赖**自己算出来带上的**(**必需**);第三组只是建议,**永远不会被自动装**。

**Q: `apt install ./x.deb` 里 `./` 为什么必须写?不写会怎样?**

A: apt 默认把参数当**仓库里的包名**。不写 → 拿文件名去仓库搜 → `Error: Unable to locate package`;写了 → 它打开文件、**读出真包名**(`Note, selecting 'figlet' instead of './...'`)。

**Q: `remove` 和 `purge` 差在哪?怎么用命令看出"包卸了但配置还在"?**

A: `remove` 只删程序、**留配置文件**;`purge` 连配置文件一起删。**看 `dpkg -l` 的状态位**:变 `rc` 就是"包没了、配置还在";`purge` 之后那一行**整个消失**。

**Q: `remove` 为什么故意留着配置文件?**

A: `man dpkg` 原文:这样可以 **avoid having to reconfigure the package if it is reinstalled later**——以后重装同一个包,改过的设置还在。

**Q: 什么包会被 `autoremove` 盯上?为什么 apt 不自己删?**

A: **当初作为依赖被自动装上、现在没有任何包再用它**的包。apt **只提示不动手**——"没人依赖"不等于"用不着",删是不可逆动作,得人点头。

**Q: `apt autoremove --dry-run` 里的 `--dry-run` 和 `-s` 是一回事吗?**

A: 是。`man apt-get` 里 `-s, --simulate, --just-print, --dry-run, --recon, --no-act` 是**同一串别名**,都是"只演示不动手"。

---

## 总结(50字以内,用自己的话概括今天学到了什么)

apt update 只搬货单不升软件;apt 在 dpkg 上层、两者都看得到本机账;`ii` 是装好、`rc` 是卸了留配置;remove 留配置、purge 连它一起删;孤儿包靠 autoremove 清。

---

## 复习卡片

| 概念 | 必学/了解 | 一句话 | 场景 |

| ---------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------ | ---------------- |

| `apt` | 必学 | Ubuntu 的**软件包管理命令**(搜/看/装/卸/升) | 装软件 |

| 仓库 repository | 必学 | 网上放软件的地方;本机配了 2 个 | 理解货单哪来 |

| 索引(货单) | 必学 | "有哪些包、什么版本"的清单,存在 `/var/lib/apt/lists/` | 理解 update |

| **`apt update`** | 必学 | **只下货单,不升软件** | 最容易搞混 |

| `apt upgrade` | 必学 | 照着货单**真升级** | 升级 |

| 为什么分两步 | 必学 | 货单旧 → 算出来的结果就旧 | 理解顺序 |

| `apt list` | 必学 | **78416** 条:仓库里全部 | 看仓库有什么 |

| `apt list --installed` | 必学 | **545** 条:本机已装 | 看装了哪些 |

| `--installed` | 必学 | 一个**过滤条件**(选项 = 命令的开关) | 理解选项 |

| `dpkg` | 必学 | 下层工具,**只认本地 `.deb`** | 理解两层 |

| `dpkg --help` 的 `-i` | 必学 | 后面跟 `<.deb file name>`——**本地文件名** | 两层的证据 |

| 两层的"视野" | 必学 | **本机装了什么,apt 和 dpkg 都看得到** | 别推成"各管一头" |

| `Inst` ↔ `--unpack` | 必学 | apt 的 `Inst` 阶段 = dpkg 解包;`Conf` = 配置 | 看装包过程 |

| `dpkg -l` 三位 | 必学 | Desired(期望)· Status(实际)· Err(坏没坏) | 读状态位 |

| `ii` | 必学 | 期望装 + 已装 + 无错 | 正常已装 |

| **`rc`** | 必学 | **r**emove + **c**onffiles remain——卸了但配置还在 | 看卸干净没有 |

| `apt search` | 必学 | 在**包的描述**里搜 | 不知道名字 |

| `apt show` | 必学 | 看一个包的完整身份(版本/依赖/大小/来源) | 装之前 |

| 交易预览三样 | 必学 | 装哪些 / `Download size` / `Space needed` | 按 Y 之前 |

| `Installing` 组 | 必学 | **你点名的** | 读预览 |

| `Installing dependencies` 组 | 必学 | apt 为满足依赖**自动带上的**——**必需,不是次要** | 读预览 |

| `Suggested packages` | 必学 | 只是建议,**apt 从不自动装** | 读预览 |

| `./` 前缀 | 必学 | 告诉 apt"这是**本地文件路径**",不是包名 | 装本地 deb |

| `remove` | 必学 | 删程序、**留配置**(`rc`) | 卸包 |

| `purge` | 必学 | 删程序 **+ 删配置**(那行整个消失) | 卸干净 |

| remove 为什么留配置 | 必学 | 重装时**不用重新配置**(`man dpkg` 原文) | 理解设计 |

| 孤儿包 | 必学 | 当初**自动装上**、现在**没人依赖** | 清理 |

| `autoremove` | 必学 | 清孤儿;**先 `--dry-run` 看,再真跑** | 清理 |

| apt 不自己删孤儿 | 必学 | 只提示——"没人依赖"≠"用不着",删得人点头 | 理解设计 |

| `[Y/n]` | 必学 | **大写 = 默认值**,回车就等于选它 | 看提示 |

| `-s` / `--dry-run` | 必学 | 只演示不动手(同一串别名) | 动手前 |

| `/var/log/apt/history.log` | 必学 | 记着谁在什么时候跑过什么(含 `Requested-By`) | 查操作历史 |

| **了解层(合并一行)** | 了解 | 本轮只带出、没深挖没考:`rpm`/`dnf`/`yum` 是 Red Hat 那家的对应体系(底层 rpm、仓库级 dnf、`yum` 在现代 RHEL 上只是 dnf 的兼容别名) | 见到再查 |

---

## 旧知识回收(今天暴露出来的)

| 概念 | 一句话 | 出处 |

| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- |

| **`ps` 后面为什么不能接进程名** | `ps` 的语法**只认选项和 PID 数字**;写 `ps python` 它把 `python` 当号码解析,报 `process ID list syntax error`。按名字找进程要用 `ps aux \| grep 名字` | 09-15 抽考答「记不得了」。探地基挖出断点在「**选项**」这个概念上——`ps aux` 里的 `a`/`x`/`u` 就是选项(选哪些 + 怎么显示) |

| **`crontab -r`** | **不是 read,是 remove**——把整个 crontab 删掉、**不可逆、还不问**。列出来看是 **`-l`**(list) | 09-15 抽考答成「第一个是只读」 |

| **`kill` 的用词** | `kill` 是**发信号**,不是"删"。默认 15 号(TERM,请它自己收尾再走);9 号(KILL)是立刻处决、来不及收尾 | 09-15 抽考方向对、用词需拧 |

---

## 今日产出验收

| 条 | 标准 | 结果 |

| --- | -------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

| ① | 亲手装一个包,读出交易预览里的三样 | ✅ 做得出(`sudo apt install figlet`,`Installing: 1` / `Download size: 138 kB` / `Space needed: 752 kB`)+ 讲得清(点 4 答案是这三样) |

| ② | 亲手做 remove → purge 对比实验 | ✅ 做得出(`ii` → `rc` → 那行消失;配置文件 290 字节 → 还在 → `No such file or directory`)+ 讲得清(点 7 答对,并自己拆出"第一位期望、第二位实际") |

| ③ | 讲清 `apt update` / `upgrade` 两步 + `./` 不写会怎样 | ✅ 做得出(跑过两条对照:不写报 `Unable to locate package`,写了报 `Note, selecting 'figlet'`)+ 讲得清(第 1 题答 `apt upgrade`;点 6 答 A 并补「`./` 是从本地找」) |

| ④ | 说出 toilet 带的两个依赖 + 指出孤儿 + 用 autoremove 清掉 | ✅ 做得出(预览 `Installing: 3` + `Installing dependencies: libcaca0 toilet-fonts`;`apt autoremove` 真跑成功)+ 讲得清(点 5 答 B、点 9 答 D) |

返回列表