Ubuntu 软件包管理主要用到了 apt 和 dpkg 两个工具。我们用的最多的就是用他们提供的命令来安装和卸载软件,但他们是如何工作的,我们也许并不十分清楚,这几天,我专门梳理了一下,以下是我整理出来的一些资料,供大家参考。
一、软件包管理器的几个重要的目录和文件
1. /var/lib/apt/lists/
软件包索引文件,apt update
之后的产物,也是 apt upgrade
读取的数据源。你在 apt update
时终端的一些提示性内容就与该目录有关。你可以试着删除 /var/lib/apt/lists/ 目录内的文件,然后执行 sudo apt update
会发现,该目录中将出现与终端提示所对应的文件。
$ ls /var/lib/apt/lists/
archive.ubuntukylin.com_ubuntukylin_dists_jammy_InRelease
archive.ubuntukylin.com_ubuntukylin_dists_jammy_main_binary-amd64_Packages
archive.ubuntukylin.com_ubuntukylin_dists_jammy_main_binary-i386_Packages
archive.ubuntukylin.com_ubuntukylin_dists_jammy_main_i18n_Translation-en
archive.ubuntukylin.com_ubuntukylin_dists_jammy-partner_InRelease
archive.ubuntukylin.com_ubuntukylin_dists_jammy-partner_main_binary-amd64_Packages
archive.ubuntukylin.com_ubuntukylin_dists_jammy-partner_main_binary-i386_Packages
auxfiles
lock
mirrors.tuna.tsinghua.edu.cn_wine-builds_ubuntu_dists_jammy_InRelease
mirrors.tuna.tsinghua.edu.cn_wine-builds_ubuntu_dists_jammy_main_binary-all_Packages
...
进阶:
APT是一个客户/服务器系统。在服务器上先复制所有 DEB 包(DEB是Debian软件包格式的文件扩展名),然后用 APT 的分析工具(genbasedir)根据每个 DEB 包的包头(Header)信息对所有的 DEB 包进行分析,并将该分析结果记录在一个文件中,这个文件称为 DEB 索引清单,APT 服务器的 DEB 索引清单置于 base 文件夹内。一旦 APT 服务器内的 DEB 有所变动,必须使用 genbasedir 产生新的 DEB 索引清单。
客户端在进行安装或升级时先要查询 DEB 索引清单,从而可以获知所有具有依赖关系的软件包,并一同下载到客户端以便安装。
当客户端需要安装、升级或删除某个软件包时,客户端计算机取得 DEB 索引清单压缩文件后,会将其解压置放于 /var/state/apt/lists/,而客户端使用 apt install 或 apt upgrade 命令的时候,就会将这个文件夹内的数据和客户端计算机内的 DEB 数据库比对,知道哪些 DEB 已安装、未安装或是可以升级的。
2. /var/lib/dpkg/
Ubuntu 中所有 软件包(packages) 的信息都放在 /var/lib/dpkg/ 目录下,下面分析一下几个重要的文件和目录:
1) /var/lib/dpkg/info
该目录用于保存各个软件包的配置信息,并用不同后缀来表示该软件包的特定信息。
文件名 | 作用 |
---|---|
*.conffiles | 记录着指定软件包所包含的所有配置文件完整路径 |
.list | 记录着指定软件包所包含的所有文件,可通过执行 dpkg -L 软件包名 来查看 |
*.md5sums | 记录了软件包的md5信息,这个信息是用来进行包验证的 |
*.preinst | 脚本文件,pre install,在 deb 包安装之前运行,通常为建立相关目录、检测系统环境等 |
*.postinst | 脚本文件,post install,在 deb 包安装之后运行,通常为开启daemon,建立菜单项和快捷方式等 |
*.prerm | 脚本文件,pre remove,在移除或重新安装该软件包前要做的工作 |
*.postrm | 脚本文件,post remove,在移除该软件包后要做的工作 |
2) /var/lib/dpkg/status
该文件列出了系统中目前存在的软件包(已安装,仅存配置,仅解压缩,不完全安装等)的一些描述信息,包括:包的状态,版本,配置文件,描述等。
如下面的 apt 包信息是从 /var/lib/dpkg/status 中复制出来的,可以看看大概包括那些内容。
Package: apt
Status: install ok installed
Priority: important
Section: admin
Installed-Size: 4156
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Architecture: amd64
Version: 2.4.9
Replaces: apt-transport-https (<< 1.5~alpha4~), apt-utils (<< 1.3~exp2~)
Provides: apt-transport-https (= 2.4.9)
Depends: adduser, gpgv | gpgv2 | gpgv1, libapt-pkg6.0 (>= 2.4.9), ubuntu-keyring, libc6 (>= 2.34), libgcc-s1 (>= 3.3.1), libgnutls30 (>= 3.7.0), libseccomp2 (>= 2.4.2), libstdc++6 (>= 11), libsystemd0
Recommends: ca-certificates
Suggests: apt-doc, aptitude | synaptic | wajig, dpkg-dev (>= 1.17.2), gnupg | gnupg2 | gnupg1, powermgmt-base
Breaks: apt-transport-https (<< 1.5~alpha4~), apt-utils (<< 1.3~exp2~), aptitude (<< 0.8.10)
Conffiles:/etc/apt/apt.conf.d/01-vendor-ubuntu c69ce53f5f0755e5ac4441702e820505/etc/apt/apt.conf.d/01autoremove ab6540f7278a05a4b7f9e58afcaa5f46/etc/cron.daily/apt-compat 1400ab07a4a2905b04c33e3e93d42b7b/etc/logrotate.d/apt 179f2ed4f85cbaca12fa3d69c2a4a1c3
Description: commandline package managerThis package provides commandline tools for searching andmanaging as well as querying information about packagesas a low-level access to all features of the libapt-pkg library..These include:* apt-get for retrieval of packages and information about themfrom authenticated sources and for installation, upgrade andremoval of packages together with their dependencies
...
Original-Maintainer: APT Development Team <deity@lists.debian.org>
同样,通过 dpkg -s 软件包名
命令也可取出该文件中相关软件包的信息,可输入 dpkg -s apt
测试内容是否与上面的内容一致。
而,通过 dpkg -l
命令则可以列表形式读取该文件中软件包的部分信息
$ dpkg -l
期望状态=未知(u)/安装(i)/删除(r)/清除(p)/保持(h)
| 状态=未安装(n)/已安装(i)/仅存配置(c)/仅解压缩(U)/配置失败(F)/不完全安装(H)/触发器等待(W)/触发器未决(T)
|/ 错误?=(无)/须重装(R) (状态,错误:大写=故障)
||/ 名称 版本 体系结构 描述
+++-=============================================-=======================================-============-==========================================================================================>
ii aapt 1:10.0.0+r36-3 amd64 Android Asset Packaging Tool
ii accountsservice 22.07.5-2ubuntu1.3 amd64 query and manipulate user account information
ii acl 2.3.1-1 amd64 access control list - utilities
ii acpi-support 0.144 amd64 scripts for handling many ACPI events
ii acpid 1:2.0.33-1ubuntu1 amd64 Advanced Configuration and Power Interface event daemon
ii adduser 3.118ubuntu5 all add and remove users and groups
ii adium-theme-ubuntu 0.3.4-0ubuntu4 all Adium message style for Ubuntu
ii adwaita-icon-theme 41.0-1ubuntu1 all default icon theme of GNOME (small subset)
ii aisleriot 1:3.22.22-1 amd64 GNOME solitaire card game collection
ii alsa-base 1.0.25+dfsg-0ubuntu7 all ALSA driver configuration files
...
3) /var/lib/dpkg/available ,可用包列表
该文件列出了系统上可用包(对应 status 查询结果)对应的老版本包的信息(注解: 应该是软件源为了照顾某些软件包或者依赖需要用到老版本,因此保留了一些旧的安装包供需要的人回退安装)。如下是该文件中保存的 apt 包的信息,其版本是 “2.4.5” ,而系统已经安装的版本是 “2.4.9”
Package: apt
Architecture: amd64
Version: 2.4.5
Priority: important
Section: admin
Origin: Ubuntu
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Original-Maintainer: APT Development Team <deity@lists.debian.org>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 4156
Provides: apt-transport-https (= 2.4.5)
Depends: adduser, gpgv | gpgv2 | gpgv1, libapt-pkg6.0 (>= 2.4.5), ubuntu-keyring, libc6 (>= 2.34), libgcc-s1 (>= 3.3.1), libgnutls30 (>= 3.7.0), libseccomp2 (>= 2.4.2), libstdc++6 (>= 11), libsystemd0
Recommends: ca-certificates
Suggests: apt-doc, aptitude | synaptic | wajig, dpkg-dev (>= 1.17.2), gnupg | gnupg2 | gnupg1, powermgmt-base
Breaks: apt-transport-https (<< 1.5~alpha4~), apt-utils (<< 1.3~exp2~), aptitude (<< 0.8.10)
Replaces: apt-transport-https (<< 1.5~alpha4~), apt-utils (<< 1.3~exp2~)
Filename: pool/main/a/apt/apt_2.4.5_amd64.deb
Size: 1379030
MD5sum: d376f3b95d73f7b9ace2dc9364d876fd
SHA1: 2a85f2cb8fbd3f51932e9fb43c3a031c60bf2c95
SHA256: 89b093ec665072b3400881120aa3f4460222caa6a5d6c6ccb3d016beb18e7a00
SHA512: 5d4e2b80ed0262dcfa9cbc3ca45e663e8e3e080691603eb464c035ad3785c595ca8915b2436ee43242b6cc904c2fd0c0a81ddd902cc2e04fb56f5afa9c1fc2b0
Description: commandline package manager
Task: minimal, server-minimal
Description-md5: 9fb97a88cb7383934ef963352b53b4a7
Build-Essential: yes
可以通过 apt-cache madison
命令来查看某个软件包有哪些可安装的软件包
$ apt-cache madison aptapt | 2.4.9 | http://mirrors.ustc.edu.cn/ubuntu jammy-updates/main amd64 Packagesapt | 2.4.5 | http://mirrors.ustc.edu.cn/ubuntu jammy/main amd64 Packages
二、软件包管理器是怎么工作的
1.apt update
干了什么
apt update
是安装和升级软件的前提,执行它之后,会做两件大事:
-
扫描软件源的每一个镜像站点服务器,并为可用的软件包资源建立若干个索引文件,从而保存到本地的 /var/lib/apt/lists/ 目录。
-
将索引文件与系统可用包进行数据比对(应该是比对了 /var/lib/apt/lists/ 和 /var/lib/dpkg/status 两个文件,至于有没有比对 /var/lib/dpkg/info 有待考证),判断那些包或者依赖需要升级,那些包需要自动卸载等。
2. apt upgrade
如何更新软件包
根据 apt update
的反馈结果,自动从软件源下载对应版本的软件包,并执行安装命令,同时更新 /var/lib/dpkg/status 文件。
3. apt install
如何安装软件包
-
检索 /var/lib/apt/lists/ 目录中的索引文件,是否存在指定安装软件包的信息。
-
检索 /var/lib/dpkg/status 文件,查看是否存在指定软件包信息,并读取状态,如已正确安装,则给出提示信息后直接退出。
-
如未安装,生成软件的依赖树,将需要的依赖包列出来并在终端予以提示,在安装所需软件之前进行安装。
-
从软件源中下载、安装依赖包和软件(下载的安装包通常保存在 /var/cache/apt/archives/ 目录下),同时更新 /var/lib/dpkg/ 目录内相关文件的内容。
三、软件包管理器使用的经验积累
1.安装提示软件包为 lock 状态
分析: 在执行 apt install
的同时,会在 /var/lib/dpkg/ 和 /var/cache/apt/archives/ 下生成 lock 文件,如果指令正常退出时,系统会删除这个 lock 文件,而出现异常退出等情况,lock 文件并不会删除,如果再次安装该软件,就会报错
办法: 删除这两个文件。
2.软件包缓存
当安装或更新软件时,首先会从软件源中下载软件包到本地的 /var/cache/apt/archives/ 目录下,再执行安装操作,久而久之,该目录内可能存有大量安装包,清理的办法是删除该目录内文件,也可通过 apt clean
命令来直接清除。当然你也可以发挥这个目录的其他用途,如复制某些软件包备用。
# 删除 /var/cache/apt/archives/ 目录内所有 deb 包
$ sudo apt clean # 删除 /var/cache/apt/archives/ 目录内过期 deb 包
$ sudo apt autoclean
3.如何删除一个软件
删除软件是安装软件的一个逆向工程,但却更加复杂。其中有人为因素考虑,如不同的人对于软件删除有不同的需求,比如他们想保留配置文件;也有历史因素,比如不同的软件都用到了依赖,删除时要判断这个依赖还需不需要,等等。
下面是几组删除命令:
# 删除软件但不删除配置文件
$ sudo apt remove packagename
$ sudo dpkg -r packagename# 删除软件以及配置文件
$ sudo apt remove packagename --purge
$ sudo apt purge packagename
$ sudo dpkg -P packagename# 删除没用的依赖包(不是主动安装,且不被任何软件依赖的包)
$ sudo apt autoremove# 清理带 “rc” (已被删除仅存配置)状态的软件包,通常用于彻底删除软件
dpkg -l | grep ^rc | awk '{print $2}' | sudo xargs dpkg -P
4. apt-cache 命令
apt-cache
是一个专门查询和显示已安装和可安装软件包信息的工具,学习它对于我们理解软件包管理器的工作原理有很大帮助。
用法: apt-cache [选项] 子命令
常用子命令:
子命令 | 描述 |
---|---|
show | 显示老版本软件包的信息(读取的是 /var/lib/dpkg/available,注意区分 dpkg -l) |
showpkg | 显示软件包的常规描述信息 |
showsrc | 显示源文件的各项记录(在软件仓库中指定了代码源的情况下有作用) |
stats | 显示软件源的基本统计信息 |
dump | 显示软件源中所有软件包的简要信息 |
dumpavail | 显示系统已安装的所有软件包的描述信息 |
unmet | 显示所有未满足的依赖关系 |
search | 根据正则表达式搜索软件包列表 |
depends | 显示该软件包的依赖关系信息 |
rdepends | 显示所有依赖于该软件包的软件包名字 |
pkgnames | 列出所有软件包的名字 |
policy | 显示软件包的安装设置状态 |
部分参考文章:
https://blog.csdn.net/Dreamby/article/details/16357921
http://www.lgwimonday.cn/archives/2091
https://blog.csdn.net/m0_68431045/article/details/128294893