系列第 5 篇|系统跑起来后,软件是怎么装进去的覆盖 Ubuntu、Debian、CentOS、Fedora;本篇重点讲清 apt
前面四篇解决的是:系统如何从断电变成「能登录、能跑程序」。本篇换一个非常实际的问题:
系统已经跑起来了,我想安装某个软件并运行它——这事在 Linux 上通常怎么做?
在 Ubuntu、Debian、CentOS、Fedora 这类主流发行版上,答案几乎总是:用包管理器。读者后续会在 WSL2 的 Ubuntu 里做 Yocto 构建,日常接触最多的是 apt,因此本篇把 apt 的工作原理、软件源配置、镜像加速讲透;yum / dnf 只作对照。
从 Windows 过来的同学,很容易把安装理解成:下载一个 exe / 绿色文件夹,拷进去就能用。在 Linux 上有时也能这么干,但很快会碰到:
.so 动态库,系统里没有或版本不对;包管理器就是为这些麻烦准备的:它不只帮你下载软件,还帮你处理依赖、把文件放到标准位置、记下「到底装过什么」,以便日后升级和卸载。
可以把仓库想成「应用商店的货架与目录」;把本地数据库想成「你家已经买过什么的收据夹」。
表面上有四个常见发行版,底层其实主要是两套体系:
.deb | |||
.rpm |
再补充两点避免晕:
apt 与 dpkg 的分工
.deb 解开安装到系统」。日常你主要用 apt 即可。yum 与 dnf 的关系在较新的 Fedora / RHEL 系里,dnf 是主力;yum 常常还在,但多为兼容入口。把下面的 apt 流程换成「dnf + rpm」,思路是一样的。
一次 sudo apt install hello 不是「下载一个文件再拷贝」,而是分层流水线。
读软件源配置 → apt update:从源下载并校验索引(目录) → 解析依赖(还要装哪些包、哪个版本) → 按索引里的地址下载 .deb → 调用 dpkg 解包、跑安装脚本、落盘 → 更新本地账本(/var/lib/dpkg/status)aptapt-get、apt-cache | ||
dpkg | .deb,执行 preinst / postinst 等脚本,改账本 |
可以记:
apt 管「买什么、从哪买、先买谁」;dpkg 管「拆箱上架、记账」。
所以你几乎不会直接 dpkg -i xxx.deb 装一堆包——那样不会自动拉依赖。缺依赖时 dpkg 会报错,把残局留给你自己收拾。
apt update 和 apt install 各干什么这两条命令最容易混:
apt update | ||
apt install | .deb,再交给 dpkg |
索引缓存在 /var/lib/apt/lists/。很久没 update,商店货架还是上周的,install 只能按旧目录采购。
apt upgrade 则是:对照新索引,把已经安装的包升到索引允许的新版本。本篇不展开升级策略,知道它和 install 一样依赖「先有一份新索引」即可。
以 Ubuntu 为例,关键路径如下。不必背全,但要能把「配置 → 索引 → 包文件 → 账本」对上号。
/etc/apt/sources.list | |
/etc/apt/sources.list.d/ | .list 或 .sources 一个文件 |
/etc/apt/apt.conf/etc/apt/apt.conf.d/ | |
/etc/apt/keyrings//usr/share/keyrings/ | |
/var/lib/apt/lists/ | apt update |
/var/cache/apt/archives/ | .deb(安装前的临时货仓) |
/var/lib/dpkg/status | |
/var/lib/dpkg/info/ |
流程用路径再说一遍:
/etc/apt/sources.list(+.d) │ 告诉 apt:去哪些 URL 找哪套发行版组件 ▼apt update → /var/lib/apt/lists/ (索引) │ ▼apt install → 算依赖 │ ▼下载 .deb → /var/cache/apt/archives/ │ ▼dpkg 安装 → 文件落到 /usr/bin、/usr/lib 等 │ ▼记账 → /var/lib/dpkg/status索引文件里对每个包都写了大小和哈希(如 SHA256)。下载完成后 apt 会核对哈希,再交给 dpkg。换镜像源之所以「只换地址、不换内容」,正是因为校验的是这份索引,而不是「信网站长什么样」。
软件源 = 告诉 apt:去哪台服务器、取哪个发行版套件、要哪些组件。
没有正确的源,apt update 拉不到索引,后面的 install 全部无从谈起。
Ubuntu / Debian 会读两处,合并生效:
/etc/apt/sources.list/etc/apt/sources.list.d/ 下所有合法的源文件常见两种写法:
.list | ||
.sources | /etc/apt/sources.list.d/ubuntu.sources |
第三方源(Docker、VS Code 等)也习惯单独丢一个文件进 sources.list.d/,避免和系统自带源搅在一个大文件里。改完源之后必须再执行一次 sudo apt update,新地址才会进入 /var/lib/apt/lists/。
deb http://archive.ubuntu.com/ubuntu jammy main restricted universe multiverse从左到右:
deb | debdeb-src = 源码包(apt source 用,构建镜像一般不需要) | |
http://archive.ubuntu.com/ubuntu | ||
jammy | ||
main restricted universe multiverse |
同一发行版通常还有更新通道,例如:
deb http://archive.ubuntu.com/ubuntu jammy-updates main restricted universe multiversedeb http://security.ubuntu.com/ubuntu jammy-security main restricted universe multiversejammy 是发行时冻结的底座;jammy-updates 是常规更新;jammy-security 是安全补丁。三条都指向「同一代系统的不同货架」,不能把 jammy 的机器改成指向 noble。
含义相同,只是写成多行,方便加签名文件路径:
Types: debURIs: http://archive.ubuntu.com/ubuntuSuites: noble noble-updatesComponents: main restricted universe multiverseSigned-By: /usr/share/keyrings/ubuntu-archive-keyring.gpgSigned-By 指定用哪把公钥验索引签名。apt 不只下载文件,还会确认「这份目录确实由发行版签过」。镜像站同步的是同一批已签名文件,所以换镜像后校验仍然成立。
apt update | |
sources.list,忘了 sources.list.d/ 里还有一份 | |
apt update | install |
官方源(如 archive.ubuntu.com、deb.debian.org)往往在海外。国内访问延迟高、带宽差,apt update 和下载 .deb 都会慢。镜像加速解决的是 同一份内容,换一个更近的下载入口。
正规镜像站会定期从官方仓库做同步(常见用 rsync 一类工具),尽量保持:
dists/ 下放索引,pool/ 下放 .deb);对 apt 来说,软件源 URI 只是「仓库根」。把
http://archive.ubuntu.com/ubuntu换成
https://mirrors.tuna.tsinghua.edu.cn/ubuntu之后,apt 请求的仍是 dists/jammy/main/.../Packages 这类相对路径。索引里的包哈希不变,下载到的 .deb 也应能通过校验。
你的机器 │ 改的只是 URI 主机名 ▼国内镜像(清华 / 阿里 / 中科大 / 华为云 …) │ 定期同步 ▼官方仓库(archive.ubuntu.com 等)所以:镜像加速 不是「换了一套不同的软件」,而是 CDN / 就近副本。快,是因为链路短、带宽够;安全边界仍然是「索引有发行版签名 + 包文件有哈希」。
只改软件源里的 URI 主机(和镜像站要求的路径前缀),套件、组件保持不动。
Ubuntu 22.04 一类 classic 格式,把 archive.ubuntu.com 换成镜像站给出的地址即可,例如:
# 官方deb http://archive.ubuntu.com/ubuntu jammy main restricted universe multiverse# 清华镜像(示例,以镜像站当前文档为准)deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy main restricted universe multiverseUbuntu 24.04 则改 /etc/apt/sources.list.d/ubuntu.sources 里的 URIs: 行。许多镜像站还提供一键脚本;原理都是改 URI,然后 sudo apt update。
安全源 security.ubuntu.com 有的镜像站也同步了(路径常叫 ubuntu-security 或合并进同一树)。改的时候对照镜像站说明,不要把 security 指到一个根本没有安全套件的目录。
WSL2 里的 Ubuntu 同样走 /etc/apt/。后续用 Yocto 在 WSL2 上编系统时,宿主自己装 gawk、git、python3 等构建依赖,走的就是这一套源;源慢,整个环境准备都会慢。
RPM 系把「源」写成 /etc/yum.repos.d/*.repo。一个 .repo 里常见:
[fedora]name=Fedorabaseurl=https://mirrors.example.com/fedora/releases/$releasever/Everything/$basearch/os/enabled=1gpgcheck=1/etc/apt/sources.listsources.list.d/ | /etc/yum.repos.d/*.repo |
apt update | dnf makecachednf install 也会按需刷新) |
/var/lib/apt/lists/ | /var/cache/dnf/ |
baseurl 换成国内镜像,原理与 apt 相同:同一套包,换近的 HTTP 入口。有的仓库用 mirrorlist= 让客户端自动挑镜像,本质仍是「官方内容的副本」。
下面命令需要你在对应发行版上操作,并且通常需要管理员权限(sudo)。
先看本机源配在哪(Ubuntu 24.04 可能主要看第二行):
cat /etc/apt/sources.listls /etc/apt/sources.list.d/再走一遍安装闭环:
# 1)按当前软件源刷新索引sudo apt update# 2)安装示例包(会解析依赖、下载 .deb、调用 dpkg)sudo apt install hello# 3)运行hello# 4)查看包元数据(来自索引 + 本机账本)apt show hello# 5)卸载(按 dpkg 账本删除文件)sudo apt remove hello过程复述:update 刷新 /var/lib/apt/lists/ → install 计算依赖并安装 → 直接输入命令名运行 → show 查看元数据 → remove 按账本卸载。
若要确认某个包是不是 dpkg 记下的,可以:
dpkg -L hello # 这个包装了哪些文件dpkg -s hello # 账本里的状态与版本sudo dnf install hellohellorpm -qi hellosudo dnf remove hello若环境以 yum 为主:
sudo yum install hellosudo yum remove hellorpm -qi 是直接问底层数据库:「hello 这个包的详细信息是什么?」——这能帮你理解「高层工具 vs 底层数据库」的分层。
很多人会问:既然 apt 这么方便,为什么还要 Yocto?
关键差别在时机:
apt installdnf install | ||
思想是相通的:都有「组件、依赖、部署」;但嵌入式或定制系统常常希望:
另外有一层容易忽略的关系:你在 WSL2 Ubuntu 上跑 Yocto 时,宿主仍用 apt 安装编译工具链和依赖。软件源与镜像是否配好,影响的是「能不能顺利开始构建」,不是「目标镜像里有没有 apt」。
所以下一篇会进入 Yocto:换一个阶段,用另一套工具,继续解决「软件如何进入系统」这个问题。
请确认自己能讲清:
/etc/apt/sources.list 与 /etc/apt/sources.list.d/;URI / 套件 / 组件各管什么。apt update 只更新索引;apt install 按索引下载并安装。