一、四种常见的软件交付形式
同一个软件,可能以四种形态到你手里:
交付形式 | 谁负责依赖和升级 | 常见位置 |
仓库 DEB/RPM | 包管理器 | /usr 、/etc |
单独下载的 DEB/RPM | 包管理器结合当前仓库 | 由软件包决定 |
预编译程序或压缩包 | 管理员 | /opt 、/usr/local |
源码构建 | 管理员 | 由编译参数决定 |
责任划分很清晰:前两种由包管理器负责依赖和升级,出问题容易追溯;后两种由管理员自己负责,包括依赖、升级、卸载的全过程。
二、什么时候才用预编译或源码
仓库没有所需版本或功能时,才考虑预编译程序或源码构建。
也就是说,优先级是仓库包优先。仓库里的版本经过验证,依赖自动处理,卸载干净。预编译程序和源码构建是补位手段,不是首选。
源码项目的常见流程是 configure 或 cmake,然后 make,最后 make install,不同项目选择其中一种配置工具。课件以 Nginx 为例:指定安装目录和运行身份,生成编译规则文件 Makefile,再编译并安装。
三、二进制兼容:编译好的程序不能随便搬家
已经编译好的程序里,写死了它期望的发行版、CPU 架构和运行库。课件总结了四个检查维度:
- 发行版与版本:Ubuntu、Debian、Rocky 等系统库有差异。
- CPU 架构:amd64、arm64、ppc64le、riscv64 等。
- 运行库与 ABI:C 库版本和 ABI 不匹配就无法运行。
- 来源与签名:确认文件来源可信。
对应的检查命令:
命令 | 作用 |
cat /etc/os-release | 查看发行版 |
uname -m | 查看 CPU 架构 |
dpkg --print-architecture | 查看系统包架构 |
file /opt/nginx/sbin/nginx | 显示二进制文件的 CPU 架构 |
ldd /opt/nginx/sbin/nginx | 显示运行时需要的共享库 |
dpkg -S /opt/nginx/sbin/nginx | 查询文件属于哪个包 |
特别说明第三组的结果:源码安装到 /opt/nginx 的文件,dpkg -S 查不到记录,因为它是源码安装,不归 APT 管理。这也从侧面印证了包管理器只认自己安装的东西。
把 Nginx 迁移到麒麟、openEuler 等系统时,先查看发行版和 CPU 架构,再确认依赖库是否满足要求。已经编译好的程序不能默认直接运行;条件不明确时,在目标系统重新编译更稳妥。
四、软件源不只是地址:镜像、缓存与离线
4.1 镜像站
常用 Ubuntu 镜像包括阿里云、清华大学、中国科学技术大学、南京大学和 Ubuntu 官方。要区分两种地址:软件仓库供 APT 下载软件包和索引,ISO 下载站提供系统安装镜像,两种地址不能混用。
4.2 两个缓存目录
目录 | 保存内容 |
/var/lib/apt/lists | 仓库索引 |
/var/cache/apt/archives | 下载的软件包 |
4.3 离线下载
Ubuntu 只下载软件包用 sudo apt install --download-only tree ;Rocky 安装 dnf-plugins-core 插件后,用 dnf download --resolve --alldeps --destdir ./packages tree 下载包及依赖。
课件强调:离线准备要记录发行版本、CPU 架构、仓库快照时间和软件包校验值。只复制一个主软件包,通常不能构成可重复的离线安装方案。这句话的意思是,离线安装的难点从来不在主包,而在主包背后的一串依赖。
五、版本管理:保持、比较与升级影响
5.1 固定版本
sudo apt-mark hold tree 可以锁定软件包,不让它被升级;apt-mark showhold 查看锁定了哪些;apt-mark unhold 解除锁定。适合场景:某个版本经过验证很稳定,不想被例行升级打破。
5.2 比较版本
返回 0 表示当前版本不低于 1.7。这是脚本化判断版本是否达标的通用写法。
5.3 升级前的影响检查
apt changelog tree | head -n 30 查看更新日志;systemctl --failed 查看失败的服务;test -f /var/run/reboot-required && cat /var/run/reboot-required 检查是否需要重启。升级前先看这三样,避免升级带来的意外。
六、授权边界:sudo 不必给完整的 root
课件 D.5 的核心思想:sudo 可以把固定管理任务授权给指定用户,不必提供完整的 root 权限。
流程是:管理用户 yangge 通过 sudoers 策略,获得受限管理动作。策略要回答四个问题:谁、在哪台主机、可切换为哪些身份、允许执行哪些命令。sudo -l 可以验证当前授权。
课件示例创建了一条只允许执行 apt update 和 apt install tree 的规则,验证后立即删除临时规则。配套的告诫很严肃:不要为包管理器添加任意参数通配。软件包维护脚本会以 root 身份运行,软件来源和允许安装的包名都属于授权边界。
七、DNF:另一套世界的对应物
Rocky、RHEL、AlmaLinux 和 openEuler 常用 RPM/DNF。管理任务和 APT 一一对应:
管理任务 | Ubuntu / Debian | Rocky / RHEL |
更新仓库索引 | apt update | dnf makecache |
搜索软件包 | apt search tree | dnf search tree |
查看包信息 | apt show tree | dnf info tree |
安装软件包 | apt install tree | dnf install tree |
删除软件包 | apt remove tree | dnf remove tree |
查询是否安装 | dpkg -l tree | rpm -q tree |
查询文件归属 | dpkg -S /usr/bin/tree | rpm -qf /usr/bin/tree |
DNF 还有三个特色能力:软件包组(dnf group install 一次准备一类工作环境,安装前要查看组内软件和事务影响)、事务历史(dnf history 可以查询软件包操作记录,dnf history undo ID 会重新计算依赖,不等同于文件系统快照,执行前还要确认仓库是否保留所需版本)、补充查询(dnf repolist、dnf list --showduplicates tree、dnf provides '*/tree')。
八、下篇小结
- 交付形式有四种,仓库包优先,预编译和源码是补位手段。
- 二进制兼容看四件事:发行版、CPU 架构、运行库与 ABI、来源签名;条件不明确就在目标系统重新编译。
- 版本可以 hold 固定,可以脚本化比较,升级前要查日志、失败服务和重启要求。
- sudo 授权可以精确到具体命令,包管理命令的来源和包名都是授权边界。
- DNF 与 APT 任务一一对应,包组、事务历史是其特色