🍓 第四章 Linux 系统管理
📄 一句话概括

命令行装软件不是「下载一个安装包双击」——而是从软件仓库取。这一节讲清 apt 这套体系:软件从哪来、索引是什么、update 和 upgrade 为什么是两件事、装/卸/清各自管什么,以及新版系统里源文件格式换了这件事。

📝 本节和前面几节的关系

3-3 已经讲过 apt 的几个基本命令——本节是它的完整版:补上体系原理、源的构成、dpkg 的分工、本地 .deb、第三方源,以及一张报错对照表。 4-4 讲了 /etc 是配置目录、/usr 是软件的家——本节里的源文件就在 /etc/apt/,装好的程序就落在 /usr/bin。 4-3 讲了权限——apt 几乎每条命令都要 sudo,原因就在那儿。

一、先立一个观念:Linux 装软件是「从仓库取」,不是「下安装包」

Windows 的习惯 Linux 的习惯
软件从哪来 各个官网下载 .exe/.msi 从「软件仓库」统一取
谁保证安全 你自己判断 仓库带签名,系统自动验签
怎么更新 每个软件各自弹窗提醒 一条命令全系统一起更新
怎么卸载 控制面板/自带卸载器 一条命令

「软件仓库(repository)」就是一台官方服务器,里面放着成千上万个软件包。树莓派的仓库主要来自 Debian(本课对应的这代是 Debian 13,代号 Trixie),再加上树莓派基金会自己加的几个包(raspi-config、摄像头工具等)。

这套体系最大的好处:你不用去官网找安装包,也不会装到「野路子」版本——因为仓库里的东西是官方编译、签名过的。

二、四个名词先分清

名词 大白话 在哪
仓库(repository) 软件商店的服务器 网址,写在「源文件」里
软件包(package) 商店里的一件商品 一个 .deb 文件
索引(index) 商店的商品目录清单 apt update 下载回来的那份
依赖(dependency) 「买 A 必须同时买 B」 每个包里都写着它需要谁
⚠️ 这一节最重要的一个区分:`update` 和 `upgrade`
  • apt update:只刷新商品清单(把仓库最新的目录下载到本机)。它不装任何东西。
  • apt upgrade:照清单去装新版本。它才是真正「更新软件」的那一步。

两者必须按顺序做:先 update(拿新清单),再 upgrade(照着装)。 新手最常见的误解就是「我 update 了怎么软件还是旧的」——因为 update 本来就不装东西。

标准组合:

sudo apt update && sudo apt full-upgrade

upgrade 和 full-upgrade 的区别(后者是老写法 dist-upgrade):

命令 特点
apt upgrade 保守:只升不删。遇到「必须卸掉某包才能升」的情况会跳过它
apt full-upgrade 彻底:允许为了升级而安装/卸载其他包。系统整体升级时用这个

树莓派上日常建议用 full-upgrade——因为系统组件环环相扣,保守模式常会「跳过一堆」。

三、源从哪来:先看一眼它长什么样

「源文件」就是一张「去哪儿取货」的清单,放在 /etc/apt/ 下。

新版系统(Debian 13/当前树莓派 OS)有个重要变化:

老格式 新格式(现在默认)
文件名 /etc/apt/sources.list、*.list /etc/apt/sources.list.d/*.sources
长相 一行一个源,以 deb 开头 多行「字段: 值」结构,叫 deb822

新格式长这样(看懂大意就行,不用背):

Types: deb
URIs: http://deb.debian.org/debian
Suites: trixie trixie-updates
Components: main non-free-firmware
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
字段 意思
Types deb=二进制包(能装的);deb-src=源码包
URIs 服务器地址
Suites 版本代号(这里是 trixie)
Components 仓库分区:main(自由软件)、contrib、non-free 等
Signed-By 用哪个公钥验签(取代了已废弃的 apt-key)

先看一眼你自己的机器:

ls -l /etc/apt/sources.list /etc/apt/sources.list.d/
cat /etc/apt/sources.list.d/*.sources
⚠️ 老教程让你改 `/etc/apt/sources.list`——**在新系统上多半是空的**

现在默认源都在 /etc/apt/sources.list.d/*.sources 里(树莓派自己的专属源也在同一个目录,文件名以 raspi 开头)。 如果你确实想用老格式,系统提供了官方迁移命令(把老的换成新的):

sudo apt modernize-sources

它会生成 .sources 文件,并把原文件改名备份成 .bak。别手动乱改——源写错会让 apt 直接罢工。

(可选) 换成国内镜像:如果你在树莓派上下载很慢,可以把 URIs 那行改成国内镜像(如清华的 https://mirrors.tuna.tsinghua.edu.cn/debian)。只改这一行,改完必须跑 sudo apt update 验证;报错就立刻改回去。

四、命令总表(这一节最该收藏的一张表)

命令 干什么 要不要 sudo 备注
apt update 刷新清单 ✅ 不装东西!
apt upgrade 升级已装(保守) ✅ —
apt full-upgrade 升级已装(彻底) ✅ 日常推荐这个
apt install 包名 装 ✅ 装的是「包名」不是「程序名」(3-3 提过)
apt remove 包名 卸程序,保留配置 ✅ 想装回来时设置还在
apt purge 包名 卸程序 + 配置 ✅ 「彻底删干净」
apt autoremove 清掉不再被需要的依赖 ✅ 装完东西后常跑一次
apt search 关键词 搜包 ❌ 输出很长,配合 grep 用
apt show 包名 看包详情 ❌ 版本、大小、依赖都在这
apt list --installed 列已装的包 ❌ 输出极长,必须配合 grep
apt policy 包名 看这个包从哪个源来/能装什么版本 ❌ 排查「装不上」时用
apt clean 清掉下载的缓存(/var/cache/apt) ✅ 卡满时的救急招之一

三条最常用的组合:

# ① 装一个工具(并顺手清掉多余依赖)
sudo apt update && sudo apt install htop && sudo apt autoremove

# ② 彻底卸载(连配置一起)
sudo apt purge 包名 && sudo apt autoremove

# ③ 查「我到底装没装」
apt list --installed 2>/dev/null | grep -i 包名
💡 `remove` 还是 `purge`?

只是不想用了 → remove;配置也想清掉 → purge。 有个实用判断:如果你打算以后还装回来,并且希望设置保留,就用 remove。 另外:卸掉程序后,它留下的用户数据(如 ~/.config/xxx)两个命令都不会动——那些属于你自己的文件,要自己删。

五、四个工具的辈分:apt、apt-get、aptitude、dpkg

新手看到教程里一会儿 apt 一会儿 apt-get,会以为有区别。 关系是这样的:

工具 定位 你该怎么用
apt 给人用的前端(有进度条、彩色提示) 日常就用它
apt-get 老前端,输出格式稳定 写脚本时用(脚本里别用 apt)
aptitude 更聪明的依赖解析器 可选,不用也没关系
dpkg 最底层:直接操作 .deb 文件 一般不直接用它装(见下节)

一句话:apt 是「柜台」,apt-get 是「老柜台」,dpkg 是「仓库管理员」——你在柜台办事,管理员在后台搬货。

dpkg 有几个查东西的功能很实用(只查不装,很安全):

dpkg -l | grep htop            # 这个包装了没、什么版本
dpkg -L htop                   # 这个包装了哪些文件(装到哪儿去了)
dpkg -S /usr/bin/htop          # 反查:这个文件属于哪个包(超好用)

六、装「网上下来的 .deb」:优先用 apt,别用 dpkg -i

有时候确实需要装一个官网下载的 .deb 文件(因为不在仓库里)。这时:

写法 评价
sudo dpkg -i xxx.deb 老写法:不会自动装依赖,装了常常报「依赖未满足」,还要再手动补
sudo apt install ./xxx.deb 推荐:注意前面有 ./;会自动解决依赖
cd ~/Downloads
sudo apt install ./xxxx.deb      # ✅ 推荐
⚠️ 非仓库软件的三个提醒

① 没有官方审核,来源要自己判断(尽量只装官网、知名项目)。 ② 它不会被 apt upgrade 自动更新——得自己盯新版本。 ③ 卸它要用包名(sudo apt purge 包名),不是用文件名。先 apt list --installed | grep 关键词 找出包名。

七、加第三方源(了解即可,动手前想清楚)

有些软件(如某些新版工具)会给你一个「加源 + 装」的说明。现在正确的方式长这样(关键是用 Signed-By 指定专用公钥,而不是老的 apt-key):

# 1. 建放钥匙的目录,把对方的公钥转成 keyring(新版推荐位置是 /etc/apt/keyrings)
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://example.com/key.gpg | sudo gpg --dearmor -o /etc/apt/keyrings/example.gpg

# 2. 建一个 .sources 文件(只描述这一个源)
sudo nano /etc/apt/sources.list.d/example.sources
#   Types: deb
#   URIs: https://example.com/debian
#   Suites: stable
#   Components: main
#   Signed-By: /etc/apt/keyrings/example.gpg

# 3. 刷新并安装
sudo apt update && sudo apt install 包名
🚨 为什么不用 `apt-key`

apt-key 已经被废弃:它是「全局信任」——一个源的钥匙能用来伪造任何仓库的包。 Signed-By 是「一对一」:这把钥匙只对这一个源有效,第三方源被攻破也伪造不了官方包。 所以老教程里那一大段 apt-key add 不只是过时,是不安全。

顺带一个安全常识:第三方源只加你真正需要、而且信任的。 加得越多,系统越脆弱、升级越容易出冲突。

八、报错对照表(你一定会用到)

报错 / 现象 原因 怎么办
E: Unable to locate package xxx ① 包名拼错 ② 没先 update ③ 不在已配置的源里 先 sudo apt update;再 apt search 关键词 确认包名(3-3 提过:搜的是包名不是程序名)
E: Could not get lock /var/lib/dpkg/lock-frontend 另一个 apt 正在跑(如自动更新、图形更新器) 等它跑完;或找出那个进程等它结束。别删 lock 文件
E: Unable to fetch … / 404 Not Found 源地址或版本代号错了(如把 trixie 写成 bookworm) 检查 *.sources 里的 URIs 与 Suites
E: The repository … is not signed / NO_PUBKEY 缺公钥 按发布方说明把公钥装成 keyring 并在 Signed-By 里引用(别用 apt-key)
dpkg: dependency problems 用 dpkg -i 装的,依赖没解决 改用 sudo apt install ./xxx.deb;已卡住就先 sudo apt --fix-broken install
E: You don't have enough free space SD 卡满了 df -h 看哪个分区(4-2)→ sudo apt clean → sudo apt autoremove
下载极慢 / 卡在 0% 源在海外 换国内镜像(第三节末)
装完命令找不到 程序可能装在 /usr/sbin(不在你的 PATH) dpkg -L 包名 \| grep bin 看它在哪

九、动手 Demo:装、查、卸,外加一次「卡满了」的急救

在树莓派上依次跑这九步(全程可逆,最后会全部清理):

# 1. 先刷新清单(不装东西,但必须有这一步)
sudo apt update

# 2. 装之前:搜一下有哪些相关的包
apt search "^htop$"                 # 精确找这个包名
apt show htop                       # 看它的版本、大小、依赖

# 3. 记住「装之前」的包数量,待会儿对账
before=$(dpkg -l | grep -c "^ii")

# 4. 装
sudo apt install -y htop

# 5. 验收:命令在哪、能不能跑
command -v htop
htop --version
dpkg -S "$(command -v htop)"        # 反查这个文件属于哪个包

# 6. 对账:是不是真的多装了东西
after=$(dpkg -l | grep -c "^ii")
echo "装之前 $before 个包,装之后 $after 个包"

# 7. 卸掉(先 remove,观察配置是否保留)
sudo apt remove -y htop
command -v htop || echo "已卸掉 ✅"

# 8. 清理不再需要的依赖
sudo apt autoremove -y

# 9. 急救演练:看一眼缓存占了多少、再清掉
du -sh /var/cache/apt/archives 2>/dev/null
sudo apt clean
du -sh /var/cache/apt/archives 2>/dev/null

看到什么算成功:

步骤 预期
2 apt show 打印一串信息,含 Version、Installed-Size、Depends
5 打印出 /usr/bin/htop;版本号正常输出;dpkg -S 回你 htop: /usr/bin/htop
6 after 大于或等于 before——多出来的就是新装的(含依赖)
7 打印「已卸掉 ✅」
9 清理前是几十到几百 MB,清理后掉到很小——这就是「SD 卡告急」时的第一招

「读结果」提示:第 5 步的 dpkg -S 是本节的隐藏彩蛋——它把「命令 ↔ 包 ↔ 文件路径」三者连了起来。以后你看到某个陌生的可执行文件,可以用它反查来历;想知道某个包装到哪儿去了,用 dpkg -L。

十、30 秒实验

验证「apt update 不装东西,apt upgrade 才装」——并且看清 upgrade 前会先告诉你「要装几个、占多少」。

# 1. 先看现在有没有可升级的
apt list --upgradable 2>/dev/null | head

# 2. 模拟一次升级:「-s」= simulate,只演不练,什么都不改
sudo apt -s upgrade | tail -n 5

# 3. 顺手把索引的最新状态拿回来(这一步本身不装东西)
sudo apt update

你会看到:第 2 步只打印一份计划(形如「X upgraded, Y newly installed, Z to remove」),系统一点变动都没有。

这 30 秒你收获的是:-s(simulate)是 apt 给你的「预演」开关。 以后要动系统级的大操作,先 -s 演一遍——这是「动手前先看清单」这条戒律在命令行里的现成工具。

十一、常见误区

自测三问 1. `apt update` 和 `apt upgrade` 各干什么?顺序能颠倒吗?(**`update` 只刷新软件清单、不装东西;`upgrade` 才按清单装新版本。顺序不能颠倒,必须先 `update`**) 2. `remove` 和 `purge` 的区别是什么?加上 `autoremove` 又是干什么的?(**`remove` 删程序留配置;`purge` 连配置一起删;`autoremove` 清掉不再被任何包依赖的「孤儿依赖」**) 3. 装网上下载的 `.deb`,推荐用哪条命令?为什么不用 `dpkg -i`?(**`sudo apt install ./xxx.deb`**——注意 `./`;因为 **`dpkg -i` 不会自动解决依赖**)

相关笔记