在 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 会自动对这次已确认的安装请求回答是:

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