Linux 上的软件安装

LinuxBeginner
立即练习

简介

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 会自动对已经检查过的安装请求回答 yes:

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 软件包的完整生命周期。