简介
Ubuntu 软件通常以软件包的形式提供。软件仓库会发布软件包文件及其元数据,其中包含名称、版本、依赖关系和下载位置等信息。apt 负责与软件仓库交互并解析依赖关系;dpkg 则在更底层管理已安装的 .deb 软件包数据库。
你将依次更新元数据、在安装前搜索软件包、检查已安装的软件包、移除软件包,并安装一个内容确定的本地 .deb 软件包。所有变更都使用可随时丢弃的练习软件包,并且可以通过软件包状态而非终端历史记录进行验证。
读取软件包状态与软件源
在本步骤中,你将区分软件仓库配置、可用元数据和已安装软件包状态。
检查已启用的软件源定义。现代 Ubuntu 镜像可能使用 .list 或 .sources 文件。下面这个只读管道会搜索这两类位置:grep -R 递归搜索,-h 隐藏源文件名,-s 抑制缺失文件提示,-E 启用扩展正则表达式中的分组模式;head 将显示结果限制为前 12 行:
grep -RhsE '^(deb |Types:|URIs:|Suites:)' /etc/apt/sources.list /etc/apt/sources.list.d 2>/dev/null | head -n 12
询问 dpkg 是否已安装 Bash。-W 用于选择软件包记录,-f 提供显示格式。${Package}、${Version} 和 ${db:Status-Status} 是 dpkg 字段,而不是 shell 变量,因为该格式位于单引号内:
dpkg-query -W -f='package=${Package} version=${Version} status=${db:Status-Status}\n' bash
dpkg-query 读取本地已安装状态。相比之下,apt-cache policy 会将已安装版本与已配置软件仓库中已知的版本进行比较:
apt-cache policy bash
保存一份稳定的已安装状态记录:
mkdir -p /home/labex/project/package-lab
dpkg-query -W -f='${Package} ${db:Status-Status}\n' bash > /home/labex/project/package-lab/bash-state.txt
cat /home/labex/project/package-lab/bash-state.txt
刷新软件仓库元数据
在本步骤中,你将刷新软件包索引,并了解 apt update 会产生什么变化。
运行:
sudo apt update
该命令会下载最新的软件仓库元数据。它不会为所有软件包安装更新版本;apt upgrade 才是用于升级已安装软件包的独立操作。
检查元数据缓存目录:
ls -ld /var/lib/apt/lists
find /var/lib/apt/lists -maxdepth 1 -type f | head
记录当前存在多少个普通元数据文件:
find /var/lib/apt/lists -maxdepth 1 -type f | wc -l | tr -d ' ' > /home/labex/project/package-lab/index-file-count.txt
cat /home/labex/project/package-lab/index-file-count.txt
搜索、检查并安装软件仓库中的软件包
在本步骤中,你将先调查软件包,再进行安装。
搜索软件包名称和描述,查找用于列出目录树的工具:
apt search '^tree$'
查看其元数据:
apt show tree
安装该软件包并处理依赖关系。sudo 提供所需的管理员权限,-y 会自动对这次已确认的安装请求回答是:
sudo apt install -y tree
验证软件包状态和命令查找结果,然后运行该工具:
dpkg-query -W -f='${Package} ${Version} ${db:Status-Status}\n' tree | tee /home/labex/project/package-lab/tree-installed.txt
command -v tree
tree -L 1 /home/labex/project/package-lab
列出该软件包提供的路径:
dpkg -L tree | head
移除软件包并验证结果
在本步骤中,你将移除练习用的软件仓库软件包,并区分相关的清理操作。
移除 tree:
sudo apt remove -y tree
remove 会删除由软件包安装的程序,但可能保留软件包配置。purge 还会删除由软件包管理的配置。autoremove 会删除那些自动安装且当前不再需要的依赖项;在真实主机上执行时,应先检查它准备移除的内容,再进行确认。
先预览依赖清理会执行哪些操作,同时不更改系统。--dry-run 会完成计算,但不会删除任何内容:
sudo apt autoremove --dry-run | tee /home/labex/project/package-lab/autoremove-preview.txt
在共享或生产主机上真正执行不带 --dry-run 的 apt autoremove 前,务必先阅读拟执行的操作。
当前 Bash 会话可能记住命令的旧路径。清除命令位置缓存,然后确认命令已消失,并记录软件包数据库状态:
hash -r
command -v tree || echo "tree command is unavailable"
dpkg-query -W -f='${db:Status-Status}\n' tree 2>/dev/null || echo "not-installed" | tee /home/labex/project/package-lab/tree-removed.txt
无论 dpkg 是否保留残留记录,都确保生成稳定的标记:
if dpkg-query -W -f='${db:Status-Status}' tree 2>/dev/null | grep -qx installed; then echo "still-installed"; else echo "not-installed"; fi > /home/labex/project/package-lab/tree-removed.txt
cat /home/labex/project/package-lab/tree-removed.txt
检查并安装本地 Deb 软件包
在本步骤中,你将检查一个准备好的 .deb 文件,通过 apt 安装它,运行其中的命令,然后将其干净地移除。
进入工作区,在不安装的情况下检查软件包元数据和内容:
cd /home/labex/project/package-lab
dpkg-deb -I labex-greeter_1.0_all.deb
dpkg-deb -c labex-greeter_1.0_all.deb
./ 前缀告诉 apt 这是一个本地文件,而不是软件仓库中的软件包名称:
sudo apt install -y ./labex-greeter_1.0_all.deb
查询并运行该软件包:
dpkg-query -W -f='${Package} ${Version} ${db:Status-Status}\n' labex-greeter
labex-greeter | tee local-package-output.txt
测试完成后移除软件包,并确认其中的命令已经消失:
sudo apt remove -y labex-greeter
if command -v labex-greeter >/dev/null; then echo "still-installed"; else echo "local-package-removed"; fi > local-package-state.txt
cat local-package-state.txt
总结
你已经区分了软件仓库元数据与已安装状态,刷新了 apt 索引,在安装前调查了软件包,验证了软件包提供的文件和命令查找结果,移除了软件仓库中的软件包,并完成了一个经过检查的本地 .deb 软件包的完整生命周期。



