Linux 软件包管理
Chen Kai BOSS

软件包管理看起来只是"装/卸/更新",但真正决定你是否少踩坑的,是两件事:第一,包里到底包含了什么(可执行文件、配置、依赖库、服务脚本),以及它们分别落在系统的哪些位置;第二,发行版的工具链差异( Debian/Ubuntu 的 dpkg/apt vs RHEL/CentOS 的 rpm/yum/dnf)会如何影响依赖解析、版本选择与回滚策略。本文先把软件包与依赖的基本概念讲清楚,再给出一套可复现的常用操作清单(包括高级用法:依赖冲突排查、版本锁定、降级、清理无用包),并补上国内环境最常见的配置(例如替换阿里云源、清华源、验证源是否生效)。最后把"装包"延伸到更贴近生产的两条路径:源码编译(以 Nginx 为例,讲清楚 configure/make/make install 分别干了什么)与二进制免安装配置(以 Java 为例),让你在遇到版本/依赖/网络限制时有可选的落地方案。

软件包的基本概念:包里有什么、为什么需要包管理器

软件包的组成

软件包是将程序、库文件、配置文件以及文档等打包在一起的文件,方便安装、升级和卸载。一个标准的软件包通常包括以下内容:

二进制可执行文件( Binary Executables)

经过编译的程序源代码,生成的可执行二进制文件。例如:

  • /usr/bin/vim:文本编辑器
  • /usr/sbin/nginx: Web 服务器
  • /usr/bin/gcc:编译器

配置文件( Configuration Files)

存放应用程序的默认配置,通常位于 /etc/ 目录下。例如:

1
2
3
/etc/nginx/nginx.conf  # Nginx 的配置文件
/etc/mysql/my.cnf # MySQL 的配置文件
/etc/ssh/sshd_config # SSH 服务端配置

重要特性:包管理器在升级时通常会保留你修改过的配置文件(不会覆盖),避免配置丢失。

共享库( Shared Libraries)

共享库是可执行文件运行时依赖的动态链接库(类似 Windows 的 .dll),通常存放在 /usr/lib//lib/ 目录下。例如:

1
2
/usr/lib/libssl.so             # OpenSSL 加密库
/lib/x86_64-linux-gnu/libc.so.6 # GNU C 标准库

为什么需要共享库?

  • 节省磁盘空间(多个程序共享同一个库)
  • 节省内存(同一个库只加载一次)
  • 方便升级(升级库后,所有依赖这个库的程序都受益)

数据文件( Data Files)

应用程序所需的数据,如数据库文件、默认资源等。例如:

1
2
/var/lib/mysql/   # MySQL 数据库存放目录
/var/www/html/ # Web 服务器默认站点目录

文档( Documentation)

软件的说明文档、手册页( man pages)、版权声明等,通常存放在 /usr/share/doc/ 目录。例如:

1
2
/usr/share/doc/nginx/README
/usr/share/man/man1/vim.1.gz # vim 的 man 手册

服务单元文件( Service Units,如果是服务)

如果是后台服务,还会包含 systemd unit 文件:

1
2
/usr/lib/systemd/system/nginx.service
/etc/systemd/system/mysql.service

为什么需要包管理器

如果没有包管理器,需要:

  1. 手动下载软件(从官网或第三方网站找下载链接)
  2. 手动解决依赖( A 依赖 B, B 依赖 C,你得一个一个装)
  3. 手动放置文件(可执行文件放哪、配置文件放哪、库文件放哪)
  4. 手动卸载(卸载时要记得删除所有文件,包括配置和依赖)
  5. 手动更新(每个软件都要去官网查有没有新版本)

包管理器的核心价值

  • 自动解决依赖: A 依赖 B,装 A 时自动装 B
  • 统一安装位置:所有软件都按规范放置,不会乱
  • 一键卸载:卸载时自动删除所有相关文件
  • 一键更新apt upgradednf upgrade 更新所有软件
  • 版本管理:可以查看、锁定、降级软件版本
  • 安全性:软件包都经过签名验证,减少恶意软件风险

Linux 主流包管理器对比

不同的 Linux 发行版使用不同的包管理器:

发行版 包格式 底层工具 高层工具 说明
Debian/Ubuntu .deb dpkg apt, apt-get 最流行的桌面和云服务器发行版
RHEL/CentOS/Fedora .rpm rpm yum (旧), dnf (新) 企业级 Linux, CentOS 8+ 和 Fedora 默认用 dnf
Arch Linux .tar.zst pacman pacman 滚动更新,软件版本最新
Gentoo 源码包 emerge portage 完全从源码编译,高度可定制
openSUSE .rpm rpm zypper 欧洲企业常用

本文主要讲 Debian/Ubuntu 的 apt/dpkg 和 RHEL/CentOS 的 yum/dnf/rpm,因为它们是最常用的。


Debian/Ubuntu 包管理: apt + dpkg

apt vs apt-get vs dpkg

工具 说明 推荐度
apt 高层工具,自动处理依赖,用户友好(颜色、进度条),推荐日常使用 ⭐⭐⭐⭐⭐
apt-get 老版高层工具,功能同 apt 但界面简陋,脚本中常用(输出稳定) ⭐⭐⭐⭐
dpkg 底层工具,直接操作 .deb 包,不会自动处理依赖(需要手动解决) ⭐⭐

推荐:日常使用 apt,脚本中使用 apt-get(输出格式更稳定)。

常用操作

更新软件源信息

1
sudo apt update  # 从软件源下载最新的包列表

这个命令只是更新本地的包列表缓存,不会升级任何软件。

搜索软件包

1
2
apt search nginx  # 搜索包含 nginx 的包
apt-cache search nginx # 同上(老命令)

查看包信息

1
2
apt show nginx  # 查看 nginx 的详细信息(版本、依赖、描述)
apt-cache policy nginx # 查看 nginx 的版本和安装状态

安装软件包

1
2
3
sudo apt install nginx  # 安装 nginx
sudo apt install nginx=1.18.0-0ubuntu1 # 安装指定版本
sudo apt install nginx -y # 自动回答 yes(不询问确认)

卸载软件包

1
2
3
sudo apt remove nginx  # 卸载 nginx(保留配置文件)
sudo apt purge nginx # 彻底卸载 nginx(删除配置文件)
sudo apt autoremove # 删除不再需要的依赖包(清理垃圾)

区别

  • remove:只删除程序文件,保留 /etc/ 下的配置文件(方便以后重新安装时恢复配置)
  • purge:连配置文件一起删(彻底卸载)

升级软件包

1
2
3
sudo apt upgrade  # 升级所有可升级的包(不删除已安装的包)
sudo apt full-upgrade # 升级所有包(必要时可以删除旧包)
sudo apt dist-upgrade # 同 full-upgrade(老命令)

区别

  • upgrade:保守升级,不删除已安装的包
  • full-upgrade:激进升级,必要时可以删除或安装包(如依赖关系变化)

查看已安装的包

1
2
3
dpkg -l  # 列出所有已安装的包
dpkg -l | grep nginx # 查看 nginx 是否已安装
apt list --installed # 同上( apt 命令)

查看包安装的文件

1
dpkg -L nginx  # 查看 nginx 安装了哪些文件

输出示例:

1
2
3
4
/usr/sbin/nginx
/etc/nginx/nginx.conf
/usr/share/doc/nginx/README
...

查看文件属于哪个包

1
dpkg -S /usr/sbin/nginx  # 查看 /usr/sbin/nginx 属于哪个包

输出:nginx-core: /usr/sbin/nginx

手动安装 .deb 包

1
2
sudo dpkg -i package.deb  # 安装 .deb 包(不会自动解决依赖)
sudo apt install -f # 修复依赖(如果上面报错)

更好的方式

1
sudo apt install ./package.deb  # apt 会自动解决依赖

高级用法

锁定包版本(防止升级)

1
2
3
sudo apt-mark hold nginx  # 锁定 nginx, prevent upgrade
apt-mark showhold # 查看被锁定的包
sudo apt-mark unhold nginx # 解锁

降级包版本

1
2
3
4
5
6
7
8
# 1. 查看可用版本
apt-cache policy nginx

# 2. 安装指定版本
sudo apt install nginx=1.18.0-0ubuntu1

# 3. 锁定版本(防止被升级)
sudo apt-mark hold nginx

清理缓存(释放磁盘空间)

1
2
3
sudo apt clean  # 删除所有下载的 .deb 包缓存(在 /var/cache/apt/archives/)
sudo apt autoclean # 只删除过时的包缓存
sudo apt autoremove # 删除不再需要的依赖包

组合使用(清理磁盘空间):

1
sudo apt autoremove && sudo apt autoclean

RHEL/CentOS 包管理: yum/dnf + rpm

yum vs dnf vs rpm

工具 说明 推荐度
dnf 新一代高层工具( CentOS 8+、 Fedora),自动处理依赖,速度更快,推荐使用 ⭐⭐⭐⭐⭐
yum 老版高层工具( CentOS 7 及更早),功能同 dnf 但较慢 ⭐⭐⭐⭐
rpm 底层工具,直接操作 .rpm 包,不会自动处理依赖(需要手动解决) ⭐⭐

推荐: CentOS 8+ 和 Fedora 用 dnf, CentOS 7 用 yum

常用操作(以 dnf 为例, yum 命令几乎一样)

更新软件源信息

1
2
sudo dnf makecache  # 从软件源下载最新的包列表
sudo dnf check-update # 检查有哪些包可以升级

搜索软件包

1
dnf search nginx  # 搜索包含 nginx 的包

查看包信息

1
dnf info nginx  # 查看 nginx 的详细信息(版本、依赖、描述)

安装软件包

1
2
3
sudo dnf install nginx  # 安装 nginx
sudo dnf install nginx-1.20.1 # 安装指定版本
sudo dnf install nginx -y # 自动回答 yes

卸载软件包

1
2
sudo dnf remove nginx  # 卸载 nginx
sudo dnf autoremove # 删除不再需要的依赖包

升级软件包

1
2
sudo dnf upgrade  # 升级所有可升级的包
sudo dnf upgrade nginx # 只升级 nginx

查看已安装的包

1
2
3
rpm -qa  # 列出所有已安装的包
rpm -qa | grep nginx # 查看 nginx 是否已安装
dnf list installed # 同上( dnf 命令)

查看包安装的文件

1
rpm -ql nginx  # 查看 nginx 安装了哪些文件

查看文件属于哪个包

1
rpm -qf /usr/sbin/nginx  # 查看 /usr/sbin/nginx 属于哪个包

手动安装 .rpm 包

1
2
sudo rpm -ivh package.rpm  # 安装 .rpm 包(不会自动解决依赖)
sudo dnf install package.rpm # 更好的方式(会自动解决依赖)

rpm 的常用操作

查询包信息

1
2
3
4
5
6
7
rpm -qa  # 列出所有已安装的包
rpm -qa | grep nginx # 查看 nginx 是否已安装
rpm -qi nginx # 查看包的详细信息
rpm -ql nginx # 查看包安装了哪些文件
rpm -qf /usr/sbin/nginx # 查看文件属于哪个包
rpm -qc nginx # 查看包的配置文件
rpm -qd nginx # 查看包的文档文件

验证包完整性

1
rpm -V nginx  # 验证包的文件是否被修改

输出示例:

1
S.5....T.  c /etc/nginx/nginx.conf

  • S:文件大小改变
  • 5: MD5 校验和改变
  • T:修改时间改变
  • c:配置文件

高级用法

锁定包版本(防止升级)

1
2
3
4
sudo dnf install 'dnf-command(versionlock)'  # 安装 versionlock 插件
sudo dnf versionlock add nginx # 锁定 nginx
dnf versionlock list # 查看被锁定的包
sudo dnf versionlock delete nginx # 解锁

降级包版本

1
2
3
4
5
# 1. 查看可用版本
dnf list --showduplicates nginx

# 2. 降级到指定版本
sudo dnf downgrade nginx-1.18.0

清理缓存

1
2
sudo dnf clean all  # 删除所有缓存
sudo dnf autoremove # 删除不再需要的依赖包

配置国内镜像源(加速下载)

Debian/Ubuntu 配置阿里云源

1. 备份原始源

1
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak

2. 替换为阿里云源

方法 1:自动替换(推荐)

1
2
sudo sed -i 's|http://.*archive.ubuntu.com|http://mirrors.aliyun.com|g' /etc/apt/sources.list
sudo sed -i 's|http://.*security.ubuntu.com|http://mirrors.aliyun.com|g' /etc/apt/sources.list

方法 2:手动编辑

1
sudo vim /etc/apt/sources.list

删除原内容,替换为(以 Ubuntu 22.04 为例):

1
2
3
4
deb http://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-backports main restricted universe multiverse

版本代号

  • Ubuntu 22.04: jammy
  • Ubuntu 20.04: focal
  • Ubuntu 18.04: bionic

3. 更新软件源

1
sudo apt update && sudo apt upgrade -y

4. 验证是否生效

1
cat /etc/apt/sources.list | grep mirrors.aliyun.com

如果看到 mirrors.aliyun.com,说明配置成功。

CentOS/RHEL 配置阿里云源

1. 备份原始源

1
sudo cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak

2. 下载阿里云源配置

CentOS 7

1
sudo curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

CentOS 8

1
sudo curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-8.repo

3. 清理并更新缓存

1
2
sudo dnf clean all
sudo dnf makecache

4. 验证是否生效

1
dnf repolist

如果看到 mirrors.aliyun.com,说明配置成功。

其他国内镜像源

  • 清华大学源: https://mirrors.tuna.tsinghua.edu.cn/
  • 中科大源: https://mirrors.ustc.edu.cn/
  • 网易源: http://mirrors.163.com/

配置方法类似,只需把 URL 换成对应的镜像站即可。


源码编译安装:从 configure 到 make install

有时候软件源里的版本太旧、或者需要自定义编译选项(如开启某个模块、优化性能),就需要从源码编译安装。

编译安装的三步曲

  1. ./configure:检查系统环境、生成 Makefile
  2. make:根据 Makefile 编译源代码
  3. make install:把编译好的文件安装到系统

实战:编译安装 Nginx( Tengine)

Tengine 是淘宝开发的 Nginx 分支,增强了性能和功能。

1. 安装编译依赖

1
2
sudo apt install build-essential libpcre3 libpcre3-dev libssl-dev zlib1g-dev  # Debian/Ubuntu
sudo dnf install gcc make pcre-devel openssl-devel zlib-devel # CentOS/RHEL

2. 下载源码

1
2
3
wget http://tengine.taobao.org/download/tengine-2.3.3.tar.gz
tar -zxvf tengine-2.3.3.tar.gz
cd tengine-2.3.3

3. 配置编译参数(./configure

1
2
3
4
5
6
./configure \
--prefix=/usr/local/nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_gzip_static_module

常用参数

  • --prefix=PATH:安装路径(默认 /usr/local/nginx
  • --with-http_ssl_module:启用 HTTPS 支持
  • --with-http_v2_module:启用 HTTP/2 支持
  • --with-http_realip_module:获取真实客户端 IP(适用于反向代理)

./configure 干了什么?

  • 检查系统是否有必需的库(如 OpenSSL 、 PCRE 、 zlib)
  • 根据你的参数生成 Makefile(编译配置文件)
  • 如果缺少依赖,会报错并提示安装

4. 编译(make

1
make -j$(nproc)  # 使用所有 CPU 核心并行编译(加速)

make 干了什么?

  • 读取 Makefile,按顺序编译源代码
  • 生成可执行文件(如 objs/nginx
  • 如果编译失败,检查是否缺少依赖或参数错误

5. 安装(make install

1
sudo make install

make install 干了什么?

  • 把编译好的文件复制到 --prefix 指定的目录(如 /usr/local/nginx
  • 创建必要的目录结构(conf/logs/html/sbin/
  • 不会创建 systemd service 文件(需要手动创建)

6. 启动 Nginx

1
2
3
/usr/local/nginx/sbin/nginx  # 启动
/usr/local/nginx/sbin/nginx -s stop # 停止
/usr/local/nginx/sbin/nginx -s reload # 重新加载配置

7. 创建 systemd service(可选)

创建 /etc/systemd/system/nginx.service

1
2
3
4
5
6
7
8
9
10
11
12
13
[Unit]
Description=Nginx HTTP Server
After=network.target

[Service]
Type=forking
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s stop
PrivateTmp=true

[Install]
WantedBy=multi-user.target

然后启用:

1
2
3
sudo systemctl daemon-reload
sudo systemctl enable nginx
sudo systemctl start nginx

二进制免安装配置:以 Java 为例

有些软件(如 Java 、 Go 、 Node.js)提供预编译的二进制包,解压即用,不需要安装。

实战:配置 Java 环境

1. 下载 JDK

从 Oracle 官网或开源镜像下载 JDK(如 jdk-17_linux-x64_bin.tar.gz)。

2. 解压到 /opt

1
2
sudo tar -zxvf jdk-17_linux-x64_bin.tar.gz -C /opt
sudo mv /opt/jdk-17* /opt/jdk-17 # 重命名为简短路径

3. 配置环境变量

编辑 ~/.bashrc(或 /etc/profile 对所有用户生效):

1
2
export JAVA_HOME=/opt/jdk-17
export PATH=$JAVA_HOME/bin:$PATH

4. 使配置生效

1
source ~/.bashrc

5. 验证

1
2
java -version
javac -version

如果显示版本号,说明配置成功。


包管理最佳实践

1. 定期更新系统

1
2
sudo apt update && sudo apt upgrade -y  # Debian/Ubuntu
sudo dnf upgrade -y # CentOS/RHEL

频率:建议每周或每月更新一次,及时修复安全漏洞。

2. 清理无用包和缓存

1
2
sudo apt autoremove && sudo apt autoclean  # Debian/Ubuntu
sudo dnf autoremove && sudo dnf clean all # CentOS/RHEL

磁盘空间不足时的排查

1
2
3
4
5
6
7
8
9
# 查看哪个目录占用最大
du -sh /* 2>/dev/null | sort -hr | head -10

# 查看包缓存占用
du -sh /var/cache/apt/archives # Debian/Ubuntu
du -sh /var/cache/dnf # CentOS/RHEL

# 清理后再检查
sudo apt clean && du -sh /var/cache/apt/archives

3. 锁定关键软件版本

如果某个软件升级后可能导致兼容性问题(如数据库、内核),建议锁定版本:

1
2
sudo apt-mark hold mysql-server  # Debian/Ubuntu
sudo dnf versionlock add mysql-server # CentOS/RHEL

4. 不要混用包管理器和编译安装

问题:如果你用 apt 装了 nginx,又用源码编译装了 nginx,会导致冲突(两个 nginx 可能监听同一个端口、配置文件位置不同)。

建议

  • 优先用包管理器( apt/dnf)安装(方便更新和卸载)
  • 只有在包管理器的版本太旧或缺少功能时,才编译安装
  • 如果编译安装,建议装到 /opt/usr/local(不要和包管理器的路径冲突)

5. 备份重要配置

修改配置文件前先备份:

1
sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak

6. 使用虚拟环境( Python/Node.js)

Python 和 Node.js 有自己的包管理器( pip/npm),建议使用虚拟环境隔离项目依赖:

  • Pythonpython3 -m venv venv
  • Node.jsnvmn 管理 Node.js 版本

总结与扩展阅读

这篇文章涵盖了 Linux 软件包管理的核心内容:

  1. ✅ 软件包的基本概念(包里有什么、为什么需要包管理器)
  2. ✅ Debian/Ubuntu 包管理( apt/dpkg 常用操作和高级用法)
  3. ✅ RHEL/CentOS 包管理( yum/dnf/rpm 常用操作和高级用法)
  4. ✅ 配置国内镜像源(阿里云源、清华源)
  5. ✅ 源码编译安装(以 Nginx 为例,讲清楚 configure/make/make install)
  6. ✅ 二进制免安装配置(以 Java 为例)
  7. ✅ 包管理最佳实践(清理、锁定版本、避免冲突)

扩展阅读

  • Debian 包管理手册: https://www.debian.org/doc/manuals/debian-reference/ch02
  • RPM 包管理手册: https://rpm-packaging-guide.github.io/
  • DNF 官方文档: https://dnf.readthedocs.io/

下一步

  • 《 Linux 进程与资源管理》:学习如何监控和限制进程的 CPU/内存使用
  • 《 Linux 用户管理》:学习如何管理用户/组/权限

到这里,建议已经从"会装包"升级到"能配置源、能编译安装、能排查依赖冲突"。包管理是 Linux 日常运维的基础技能,掌握了它,你就能更好地管理服务器。

  • 本文标题:Linux 软件包管理
  • 本文作者:Chen Kai
  • 创建时间:2019-12-19 14:45:00
  • 本文链接:https://www.chenk.top/Linux-%E8%BD%AF%E4%BB%B6%E5%8C%85%E7%AE%A1%E7%90%86/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
 评论