apt vs yum:面向系统管理员的 Linux 软件包管理详解
Linux软件包管理是在Linux系统上安装、更新、配置和删除软件的机制。apt(高级软件包工具)在基于Debian的发行版(如Ubuntu和Linux Mint)上处理`.deb`软件包,而yum(Yellowdog更新修改器)在基于Red Hat的系统(包括CentOS和RHEL)上管理`.rpm`软件包。这两个工具都抽象了依赖关系解析、仓库交互和软件包完整性验证的复杂性——但它们在架构上是不同的,不可互换。
了解哪个工具管理您的系统不是可选知识。它直接影响您如何配置服务器、自动化部署、编写配置管理脚本(Ansible、Chef、Puppet),以及在生产环境中维护安全补丁周期。
什么是Linux软件包管理器
软件包管理器是一套软件工具,可自动化Linux系统上软件的完整生命周期:从远程仓库获取软件包、验证加密签名、解析并安装依赖链、执行安装前/后脚本,以及在本地软件包数据库中注册安装信息。
软件包数据库至关重要,但常被忽视。在基于Debian的系统上,它位于`/var/lib/dpkg/`。在基于RPM的系统上,它位于`/var/lib/rpm/`。这两个数据库都维护着已安装内容、版本及文件所有权的权威记录——使其成为系统审计和回滚操作的支柱。
软件包管理器与仓库交互——仓库是托管经过整理的已编译、已签名软件包集合的远程服务器。仓库元数据(软件包列表、校验和、GPG密钥)在任何安装发生之前都会在本地同步,这就是为什么`apt update`或`yum check-update`必须在自动化脚本中的安装命令之前执行。
apt:基于Debian系统的高级软件包工具
apt是Debian、Ubuntu、Linux Mint、Pop!_OS及所有衍生版本上软件包管理的高级命令行界面。它运行在底层`dpkg`工具之上,该工具处理实际的`.deb`软件包安装。可以将`dpkg`视为引擎,将`apt`视为知道从哪里获取燃料以及按什么顺序燃烧的智能驾驶员。
apt工具链深度解析
apt生态系统包含几个具有不同用途的二进制文件:
- `apt` — 现代推荐的交互式CLI(在Ubuntu 14.04 / Debian 8中引入)
- `apt-get` — 较旧的可脚本化后端;由于其稳定的输出格式,在shell脚本中更受青睐
- `apt-cache` — 查询本地软件包缓存中的元数据、描述和依赖关系图
- `dpkg` — 底层软件包安装程序;在使用`dpkg -i package.deb`安装本地`.deb`文件时直接使用
- `apt-mark` — 将软件包标记为保留、自动安装或手动安装
核心apt命令及技术背景
更新本地软件包索引:
“`bash
sudo apt update
“`
这会从`/etc/apt/sources.list`和`/etc/apt/sources.list.d/`中所有已配置仓库获取更新的元数据。它不会安装或升级任何内容。在任何安装操作之前运行此命令是强制性的——跳过它意味着您可能解析到过时的软件包版本或错过安全补丁。
升级已安装的软件包:
“`bash
sudo apt upgrade
“`
升级所有存在较新版本的软件包,但不会删除任何当前已安装的软件包,也不会安装新软件包来满足依赖关系。对于处理依赖关系变化的更激进升级:
“`bash
sudo apt full-upgrade
“`
`full-upgrade`(前身为`dist-upgrade`)将根据需要安装新依赖项并删除冲突的软件包。在生产系统上谨慎使用。
安装软件包:
“`bash
sudo apt install package_name
“`
在单个事务中安装多个软件包:
“`bash
sudo apt install nginx curl git
“`
将安装合并到一个命令中更高效,因为apt只需解析一次完整的依赖关系图,而不是反复解析。
删除软件包(保留配置文件):
“`bash
sudo apt remove package_name
“`
清除软件包(删除二进制文件和配置文件):
“`bash
sudo apt purge package_name
“`
在停用服务时,始终优先使用`purge`而非`remove`。`remove`遗留的配置文件在软件包重新安装后可能导致意外行为。
删除孤立依赖项:
“`bash
sudo apt autoremove
“`
这经常被忽视,随着时间推移会导致依赖关系膨胀。将其纳入您的常规维护工作流程。
搜索软件包:
“`bash
apt search package_name
“`
安装前检查软件包详情:
“`bash
apt show package_name
“`
这会显示软件包版本、安装大小、依赖关系和维护者——在引入不熟悉的软件包之前非常有用。
将软件包保持在当前版本(对生产稳定性至关重要):
“`bash
sudo apt-mark hold package_name
“`
这可防止`apt upgrade`触及该软件包。当您运行特定内核版本或固定的应用程序版本时必不可少。
实际apt用例:在Ubuntu上配置Web服务器
“`bash
sudo apt update
sudo apt install -y nginx certbot python3-certbot-nginx
sudo systemctl enable nginx
sudo systemctl start nginx
“`
`-y`标志会抑制确认提示,这对于非交互式配置脚本是必需的。始终在同一脚本块中将其与`apt update`配对,以确保从当前仓库元数据进行安装。
yum:基于RPM系统的Yellowdog更新修改器
yum是Red Hat Enterprise Linux(RHEL)、CentOS 7和较旧Fedora版本的软件包管理器。它管理`.rpm`软件包并位于RPM数据库之上。与apt在dpkg之上一样,yum在原始`rpm`命令之上提供依赖关系解析和仓库管理。
重要架构说明:在CentOS 8+、RHEL 8+和所有现代Fedora版本上,yum已被dnf(Dandified YUM)取代。在这些系统上,`yum`命令通常是指向`dnf`的符号链接或别名。如果您管理任何运行RHEL/CentOS 8或更高版本的系统,您应该编写`dnf`命令。命令语法基本兼容,但dnf提供了明显更好的依赖关系解析、更简洁的API和模块化仓库支持。
核心yum命令及技术背景
检查可用更新而不应用它们:
“`bash
sudo yum check-update
“`
这在自动化监控脚本中特别有用,可以检测系统是否落后于补丁,而不触发升级。
应用所有可用更新:
“`bash
sudo yum update
“`
与`apt upgrade`不同,`yum update`还会根据需要安装新的依赖软件包。没有单独的`full-upgrade`等效命令——yum默认处理此问题。
安装软件包:
“`bash
sudo yum install package_name
“`
删除软件包:
“`bash
sudo yum remove package_name
“`
注意:yum的删除操作有时会级联删除依赖软件包。在确认之前,请务必查看事务摘要。
搜索软件包:
“`bash
yum search package_name
“`
检查软件包信息:
“`bash
yum info package_name
“`
列出已安装的软件包:
“`bash
yum list installed
“`
清理本地缓存:
“`bash
sudo yum clean all
“`
清除缓存的软件包数据和元数据。当您怀疑过时的仓库数据导致解析失败时运行此命令。
将软件包保持在当前版本:
“`bash
sudo yum versionlock add package_name
“`
需要`yum-plugin-versionlock`插件。相当于`apt-mark hold`,这对于维护稳定的生产环境至关重要,在这些环境中特定软件包版本不得被自动更新触及。
实际yum用例:在CentOS 7上部署Apache
“`bash
sudo yum install -y httpd
sudo systemctl enable httpd
sudo systemctl start httpd
sudo firewall-cmd –permanent –add-service=http
sudo firewall-cmd –reload
“`
一个常见错误是安装Apache后忘记开放防火墙。在CentOS/RHEL系统上,`firewalld`默认处于活动状态,即使服务正在运行,也会静默阻止HTTP流量。
apt与yum:直接比较
| 功能 | apt(Debian/Ubuntu) | yum / dnf(RHEL/CentOS/Fedora) |
|---|
| — | — | — |
|---|
| 软件包格式 | `.deb` | `.rpm` |
|---|
| 底层工具 | `dpkg` | `rpm` |
|---|
| 主要发行版 | Debian、Ubuntu、Mint、Pop!_OS | RHEL、CentOS、Fedora、AlmaLinux、Rocky Linux |
|---|
| 后继者/现代CLI | `apt`(取代`apt-get`用于交互使用) | `dnf`(在RHEL 8+上取代`yum`) |
|---|
| 依赖关系解析 | 自动,处理冲突 | 自动;dnf比yum更健壮 |
|---|
| 仓库配置 | `/etc/apt/sources.list`、`/etc/apt/sources.list.d/` | `/etc/yum.repos.d/*.repo` |
|---|
| 软件包保留机制 | `apt-mark hold` | `yum versionlock`(需要插件) |
|---|
| 本地软件包安装 | `dpkg -i file.deb` | `rpm -i file.rpm`或`yum localinstall` |
|---|
| 缓存管理 | `apt clean`、`apt autoclean` | `yum clean all` |
|---|
| 孤立软件包删除 | `apt autoremove` | `yum autoremove`(dnf处理得更好) |
|---|
| 事务历史 | 有限 | 通过`yum history`提供完整事务历史和回滚功能 |
|---|
| 模块流 | 原生不支持 | 在dnf中支持(应用流) |
|---|
| GPG签名验证 | 是 | 是 |
|---|
| 脚本友好标志 | `-y`(非交互式) | `-y`(非交互式) |
|---|
dnf:yum的现代继承者
如果您管理任何RHEL 8+、CentOS Stream、AlmaLinux、Rocky Linux或Fedora系统,dnf是您的软件包管理器。从yum到dnf的过渡不仅仅是外观上的——dnf解决了yum中一些长期存在的架构问题:
- 依赖关系解析:dnf使用`libsolv`库,比yum的解析器明显更快、更准确
- API稳定性:dnf为脚本编写和自动化提供了稳定的Python API
- 模块流:dnf支持应用流,允许同一软件的多个版本(例如PHP 7.4和PHP 8.1)在仓库中共存
- 事务回滚:`dnf history undo <id>`允许您回滚特定事务——这是apt中没有直接等效功能的能力
与yum不同的关键dnf命令:
“`bash
Install a module stream (e.g., PHP 8.1)
sudo dnf module enable php:8.1
sudo dnf install php
Roll back the last transaction
sudo dnf history undo last
Check which package provides a specific file
sudo dnf provides /usr/bin/python3
“`
仓库管理:关键的操作技能
apt和yum/dnf的实用性取决于它们配置使用的仓库。配置错误或不受信任的仓库是重大安全风险。
在Debian/Ubuntu上,安全添加第三方仓库:
“`bash
Import the GPG key
curl -fsSL https://example.com/gpg.key | sudo gpg –dearmor -o /usr/share/keyrings/example-archive-keyring.gpg
Add the repository with key reference
echo "deb [signed-by=/usr/share/keyrings/example-archive-keyring.gpg] https://repo.example.com/apt stable main" | sudo tee /etc/apt/sources.list.d/example.list
sudo apt update
“`
在RHEL/CentOS上,添加仓库:
“`bash
sudo yum-config-manager –add-repo https://repo.example.com/centos/example.repo
Or manually create /etc/yum.repos.d/example.repo
“`
安全原则:在独立验证GPG密钥之前,切勿添加仓库。被攻击的仓库可以推送恶意软件包,这些软件包将以root权限安装。
为您的服务器环境选择正确的软件包管理器
您使用的软件包管理器由您的Linux发行版决定——您不能独立选择apt或yum。您所选择的是您的发行版,这个决定对软件包可用性、企业支持合同、安全补丁节奏和工具兼容性都有下游影响。
- Ubuntu LTS(apt):适用于通用VPS托管工作负载、Web服务器和开发者环境的最佳选择。长期支持版本可获得5年安全更新,通过Ubuntu Pro可延长至10年。
- RHEL / AlmaLinux / Rocky Linux(dnf):企业生产环境的标准,特别是在需要认证软件栈、合规框架(PCI-DSS、HIPAA)或ISV支持的应用部署的独立服务器上运行时。
- Debian Stable(apt):软件包版本极为保守,非常适合优先考虑稳定性而非前沿软件的服务器。常用于长期运行的数据库和邮件服务器。
- CentOS Stream / Fedora(dnf):适用于开发和测试环境,在这些环境中您希望在稳定版本发布之前跟踪上游RHEL变化。
在部署cPanel等控制面板时,底层软件包管理器非常重要。cPanel官方支持AlmaLinux、Rocky Linux和CloudLinux——均基于dnf。如果您使用带cPanel的VPS,您将在现代部署中使用dnf环境。
对于需要图形化或基于Web的界面来管理软件包和服务器配置而无需进入命令行的环境,请探索VPS控制面板,这些面板将软件包管理抽象为UI,同时在底层仍然利用apt或dnf。
通过软件包管理进行安全加固
软件包管理器是供应链攻击的主要攻击面。这些做法在任何面向互联网的服务器上都是不可妥协的:
- 启用自动安全更新 — 在Ubuntu上:`unattended-upgrades`软件包。在RHEL/CentOS上:`dnf-automatic`,在`/etc/dnf/automatic.conf`中配置`apply_updates = yes`。
- 验证GPG签名 — 切勿在隔离实验室环境之外禁用GPG检查(yum/dnf中的`–nogpgcheck`或apt中的`–allow-unauthenticated`)。
- 定期审计已安装的软件包 — 使用`dpkg -l`或`rpm -qa`生成完整的软件包清单。将其与已知良好的基准进行对比。
- 删除不必要的软件包 — 每个已安装的软件包都是攻击面。在主要部署后运行`apt autoremove`或`dnf autoremove`。
- 固定关键软件包 — 使用`apt-mark hold`或`dnf versionlock`防止在生产系统上意外升级内核、OpenSSL或数据库引擎等软件包。
如果您运行邮件服务器或托管电子邮件基础设施,保持Postfix、Dovecot及其TLS依赖项的最新状态尤为关键。将严格的软件包管理与正确配置的SSL证书配合使用,以维护加密传输安全。同样,通过共享虚拟主机平台管理的Web托管环境受益于托管提供商维护底层软件包安全,但了解软件包层对于调试和自定义配置仍然很有价值。
实用决策矩阵和关键要点
在生产系统上运行任何软件包管理命令之前,请完成以下检查清单:
操作前检查清单:
- 确认您正在运行的发行版和版本:`cat /etc/os-release`
- 确认正确的软件包管理器:`which apt`或`which dnf`或`which yum`
- 在apt系统上:在`apt install`或`apt upgrade`之前始终运行`sudo apt update`
- 在yum/dnf系统上:升级前运行`sudo yum check-update`或`sudo dnf check-update`
- 在确认任何安装或删除操作之前查看事务摘要
- 对于生产服务器:首先在测试环境中测试软件包升级
- 重大升级后:使用`systemctl status <service>`验证服务状态
- 删除软件包后:运行`apt autoremove`或`dnf autoremove`清理孤立软件包
架构决策:
- 仅在您理解并接受软件包可能被删除的情况下,使用`apt full-upgrade`而非`apt upgrade`
- 在运行RHEL 8 / CentOS 8或更高版本的任何系统上,使用`dnf`而非`yum`
- 在shell脚本和CI/CD流水线中使用`apt-get`(而非`apt`),以获得稳定、可解析的输出
- 在任何自动化更新流水线触及生产服务器之前,使用`yum versionlock`或`apt-mark hold`
- 在导入并验证GPG密钥之前,切勿添加第三方仓库
常见问题
apt和apt-get有什么区别?
`apt`是现代面向用户的命令,旨在将`apt-get`和`apt-cache`整合为一个具有更简洁输出和进度条的单一工具。`apt-get`仍然可用,在脚本中更受青睐,因为其输出格式在各版本之间保证稳定。对于交互式终端使用,`apt`是当前标准。
我可以在CentOS或RHEL服务器上使用apt吗?
不可以。apt专用于基于Debian的系统,管理`.deb`软件包。CentOS和RHEL使用RPM软件包格式,由yum或dnf管理。软件包格式和数据库在架构上不兼容——没有转换层。
yum中apt autoremove的等效命令是什么?
`sudo yum autoremove`或`sudo dnf autoremove`删除作为依赖项安装但不再被任何明确安装的软件包所需的软件包。dnf实现比旧版yum版本更可靠。
如何防止特定软件包被apt或yum升级?
在基于apt的系统上:`sudo apt-mark hold package_name`。在yum/dnf系统上:安装`yum-plugin-versionlock`插件并运行`sudo yum versionlock add package_name`,或在dnf上:`sudo dnf versionlock add package_name`。两种机制在明确释放之前都能在`upgrade`和`update`命令中保持有效。
yum在2024年还有意义吗?
对于仍在生产中运行的CentOS 7和RHEL 7系统,是的——yum仍然是软件包管理器。然而,CentOS 7已于2024年6月达到生命周期终止。任何仍在运行CentOS 7的系统都应迁移到AlmaLinux 8/9或Rocky Linux 8/9,两者均使用dnf。编写专门针对yum的新自动化脚本不再可取。
