世界各地的软件包:探索 Arch Linux 中的软件包
大家好!我是大聪明-PLUS!

Arch Linux 软件包
最近,社区对 Arch Linux 发行版的兴趣日益浓厚:它成为了 SteamOS 的基础,PewDiePie开始使用它,Ruby on Rails的创始人也创建了自己的版本。黑客也变得活跃起来,开始向 Arch 用户仓库分发恶意软件。在讨论该发行版时,经常会提到它的软件包管理器 pacman。关于它的使用信息很容易在网上找到。但是,当我们运行 [sudo pacman -S firefox或sudo pacman -Syu] 时,究竟会发生什么呢?
在本文中,我们将详细介绍如何在 Arch Linux 中使用软件包:它们是什么、如何创建和分发它们、元软件包与软件包组有何不同,以及 pacman 存储了哪些关于它们的信息。本文面向熟悉命令行的用户。如果您对此感兴趣但尚未安装 Arch,也没关系:所有命令都可以在 Docker 容器中运行;相关说明已包含在内。
您需要打包吗?
要在 Linux 上安装程序,通常使用称为包管理器的特殊程序。例如,无需从官方网站下载 Firefox,只需在终端中输入 [unclear],sudo pacman -S firefox浏览器就会安装在您的系统上。Pacman 是 Arch Linux 包管理器的名称,是 Package Manager 的缩写。
使用包管理器为管理程序提供了更多的可能性:
-
批量安装、更新和删除程序。
-
按描述搜索程序。
-
获取程序在系统上安装的文件列表。
让我们下载该软件包lazygit但不安装它:
sudo pacman -Sw lazygit
让我们看看 pacman 下载了哪些文件:
cd /var/cache/pacman/pkg
ls | grep lazygit
输出将包含两个文件(阅读本文时的版本可能较新):
-
lazygit-0.54.0-1-x86_64.pkg.tar.zst— 以 zstd 压缩的档案形式的包。 -
lazygit-0.54.0-1-x86_64.pkg.tar.zst.sig— 带有签名的文件。允许包管理器检查包是否可信。
让我们看一下档案的内容:
tar tf lazygit-*-x86_64.pkg.tar.zst
结论
首先,请注意,存档结构反映了文件系统结构。例如,存档包含一个文件usr/bin/lazygit——程序的可执行文件。在安装过程中,它将被解压成/usr/bin/lazygit一个 .
此外,该档案还包含 3 个特殊文件,pacman 可以从中提取有关该包的信息:
.PKGINFO— 包含有关包裹的基本信息。
.PKGINFO
-
pkgname— 包名称 -
pkgver— 软件包版本 -
depend— 程序正常运行所需的其他软件包的名称 -
makedepend— 编译所需但执行时不需要的包名。这里指的是 Go 编译器,因为程序是用 Go 语言编写的。 -
size— 解压后的包文件的大小(以字节为单位)。
.BUILDINFO— 包含软件包构建环境的描述。用于可重复的构建。
.BUILDINFO
.MTREE— 包含软件包文件结构的信息。用于完整性检查。它是二进制文件,所以我就不加了。
安装/更新/删除某些软件包时,必须执行脚本。在这种情况下,软件包会包含一个.INSTALL包含相应命令的文件。
现在我们已经熟悉了软件包的结构,让我们弄清楚 pacman 如何在我们的设备上管理它们。
帕克托夫伯爵住在哪里?
在上一节中,我们了解到它 .PKGINFO包含软件包的基本信息。该文件的一个重要功能是描述依赖项——即程序正常运行所需的其他软件包。正如你可能猜到的那样,这些软件包可能有自己的依赖项,而这些依赖项又可能有自己的依赖项,依此类推,直到核心软件包。
解决依赖关系的一种简单方法是:
-
下载软件包
-
解包
-
计算依赖关系
.PKGINFO -
对每个尚未安装的依赖项执行步骤 1。
这种方法正式解决了问题,但更好的方法是提前了解依赖关系图,而无需下载软件包。以下是几个可以显著改善用户体验的示例:
-
提前了解依赖关系图可以让你尽可能并行地下载软件包,从而更好地利用网络。Pacman 使用并行下载,该功能可以通过以下参数配置
ParallelDownloads:/etc/pacman.conf -
某些软件包可能与其他软件包冲突。提前了解依赖关系图可以让您无需下载任何软件包即可检测到冲突。
因此,pacman 会从服务器下载一个压缩包数据库。更准确的说是“数据库”,因为可能有多个,稍后会详细介绍。它们位于一个目录中/var/lib/pacman/sync,名称以 结尾.db。
让我们看看数据库的内容extra.db(是的,它只是一个档案):
tar tf /var/lib/pacman/sync/extra.db
输出将会像这样
0ad-a27.1-1/
0ad-a27.1-1/desc
0ad-data-a27.1-1/
0ad-data-a27.1-1/desc
也就是说,每个包都会存储一个带有描述的文件。
lazygit-0.54.0-1/desc
如果你看一下它的内容,它会有点让人想起.PKGINFO,但它有一些关于存档文件的附加字段:
-
CSIZE— 压缩包的大小。pacman 可以使用这些信息在安装包之前确定下载文件的大小。 -
SHA256SUM— 用于完整性验证的校验和。 -
PGPSIG— 使用 base64 数字签名来验证该数据包是否可信。
值得注意的是,这些文件desc只存储文件总大小,而不是文件列表。为什么需要它呢?
例如,我们看到有人在线使用命令nslookup,但没有同名的包。如何找出哪个包包含这样的程序?我们知道程序安装在 目录中/usr/bin/。因此,我们运行以下命令
pacman -F /usr/bin/nslookup
但有些事情是错误的:
warning: database file for 'core' does not exist (use '-Fy' to download)
warning: database file for 'extra' does not exist (use '-Fy' to download)
问题是,文件列表存储在单独的数据库中。要下载它,你需要运行
sudo pacman -Fy
此后,
pacman -F /usr/bin/nslookup
它将返回给我们包含该程序的包的名称nslookup:
usr/bin/nslookup is owned by extra/bind 9.20.11-1
现在我们知道它是包的一部分bind,让我们检查一下:
sudo pacman -S bind
nslookup habr.com
事实上,我们得到了
Server: 192.168.1.1
Address: 192.168.1.1#53Non-authoritative answer:
Address: 178.248.237.68
让我们看看数据库目录中发生了什么变化:
ls /var/lib/pacman/sync
core.db core.files extra.db extra.files
这些文件.files包含包中的文件列表。默认情况下,仅从服务器下载文件.db,要下载,.files您需要运行sudo pacman -Fy。
现在让我们弄清楚“core和”的含义extra。在 Arch Linux 中,官方软件包被划分为不同的存储库,每个存储库对于包含和测试软件包有不同的规则。
-
core包含关键系统组件,例如引导加载程序和内核。软件包在发布前经过全面测试。 -
该存储库
extra包含不太重要的组件。 -
此仓库
multilib包含 32 位软件包(例如 Steam)。默认情况下不启用,但可以在 中启用/etc/pacman.conf。 -
这三个仓库各自都有
-testing一个“孪生”仓库用于测试。例如,在到达仓库 之前core,软件包会先经过core-testing,extra进入extra-testing,multilib再进入multilib-testing。
pacman 不仅会将仓库与服务器同步,还会在目录中存储已安装软件包的数据库/var/lib/pacman/local。该数据库包含已安装软件包的版本信息以及安装原因:显式安装还是作为依赖项安装。
使用本地数据库的有用命令:
注意到所有这些命令都以pacman -Q- 开头吗?这不是巧合。
选项-S、-F和-Q分别对应于它们交互的三种类型的数据库:
-
pacman -S与同步数据库交互.db -
pacman -F使用文件数据库.files -
pacman -Q拥有当地基地
安装系统时,会安装一个元包base。“元包”是什么意思?我们来看看它在系统上安装的文件列表:
pacman -Fl base
输出为空,这意味着它没有在系统上安装任何文件。那么为什么需要这个包呢?让我们从本地数据库中查看它的信息:
pacman -Qi base
结论
它的依赖项列出了系统运行所需的基本组件,包括pacman通过软件包安装的软件包管理器本身。值得注意的是,它没有linux内核软件包。这并非疏忽——开发人员允许用户安装最适合其需求的内核。
如果开发人员决定系统需要另一个软件包才能正常运行,他们只需将其添加到依赖项中base,pacman 就会在更新时下载它。因此,元包只是定义了一组依赖项的包。
有一个相关的实体——软件包组。例如,如果您要安装 KDE Plasma 环境,可以安装软件包组plasma。但是,不存在具有该名称的软件包plasma:
pacman -Si plasma
error: package 'plasma' was not found
问题是,Plasma 不是一个软件包,而是一组软件包。环境本身包含在软件包中plasma-desktop,但您不太可能只需要它。您可能还需要安装设置应用程序和系统监视器,而这些都是单独的软件包。
让我们考虑一下元包和包组之间的区别:
| 元包 | 包组 | |
| 安装 | 像普通包裹一样 | 安装时,pacman 会询问要安装组中的哪些软件包。 |
| 依赖项 | 全部安装完毕 | 选定的已安装 |
| 新的依赖项 | 更新期间安装 | 更新期间未安装 |
| 删除依赖项 | 如果不删除元包,则无法删除 | 无需删除组中的其他软件包即可删除 |
因此,元包是一个常规包,而安装包组与安装其各个包相同。元包赋予开发人员更多控制权,而包组赋予用户更多控制权。
现在是时候了解软件包数据库和软件包本身从哪里下载了。
让我们看一下 pacman 配置:
cat /etc/pacman.conf
# ...
[core]
Include = /etc/pacman.d/mirrorlist
# ...
[extra]
Include = /etc/pacman.d/mirrorlist
# ...
换句话说,服务器列表存储在一个文件中。这些服务器被称为镜像,因为它们反映了官方软件仓库的状态。镜像的主要特征是其地理位置和软件包更新的及时性。有些镜像的更新速度比其他镜像更快。您可以使用生成器/etc/pacman.d/mirrorlist按位置创建镜像列表。您还可以在专门的页面查看更新的及时性。
为了更好地了解服务器上存储的内容,您可以获取镜像的地址并在浏览器中打开它。例如,有一个名为repository.su的镜像。如果您进入该目录/core/os/x86_64/,您会看到每个软件包都有两个在安装过程中下载的文件:.pkg.tar.zst和.sig。此外,还有我们熟悉的core.db和core.files这两个文件。所以,镜像并不复杂——它只是一个通过 HTTPS 提供文件的常规 Web 服务器。依赖管理和其他逻辑都在 pacman 中实现。
Arch 使用双层镜像系统。第二层镜像从第一层镜像中提取软件包,而第一层镜像则直接从 archlinux.org 中提取软件包。第一层镜像的要求更高,必须已经是第二层镜像一段时间,并且拥有良好的声誉。
需要注意的是,镜像仅存储软件包的最新版本。这意味着,如果.db本地数据库中列出了软件包的旧版本,但服务器上已有较新版本,则您在尝试安装该软件包时会遇到错误404。合理的解决方案是先更新数据库pacman -Sy,然后再安装该软件包。但是,强烈建议不要这样做。这是因为该软件包的依赖项可能也会更新,而系统上的其他软件包可能仍然依赖于它们的旧版本。因此,建议在pacman -Syu安装该软件包之前更新系统上的所有软件包。
您可能会想:如何阻止有人创建恶意镜像并上传包含恶意软件的软件包?文件就是为了防止这种情况发生.sig。在安装软件包之前,pacman 会验证签名是否由用户信任网络中包含的密钥生成。Arch Linux 开发者密钥会在系统安装过程中随软件包一起安装archlinux-keyring。您可以自行承担风险,将其他密钥添加到信任网络。
因此,如果 Arch Linux 系统长时间不更新,可能会出现以下问题:
-
第一级困难是,用于签名软件包的密钥发生更改,导致 pacman 拒绝安装使用新密钥签名的软件包。在这种情况下,您可以单独更新密钥
sudo pacman -Sy archlinux-keyring,然后再更新系统。这不会违反信任网,因为新软件包archlinux-keyring是使用受信任的密钥签名的。 -
如果系统长时间未更新,则会出现第二级风险。此时,软件包本身
archlinux-keyring可能使用系统不信任的密钥进行签名。在这种情况下,必须禁用密钥验证,从而破坏信任网络。因此,出于安全考虑,定期更新系统至关重要。
厨师的食谱
在软件包发布到软件仓库并随后发布到镜像之前,必须有人对其进行准备。准备工作是一个 PKGBUILD 文件——一个包含创建软件包所需信息的 bash 脚本。准备材料是程序的源代码或二进制文件。在官方 Arch Linux 软件仓库中,出于安全考虑,开源软件包是在开发者的基础设施上从源代码构建的。
用于构建官方软件包的 PKGBUILD 文件位于项目的官方 GitLab上。
软件包构建
这里的许多字段我们已经很熟悉了.PKGINFO,但以下是值得关注的:
-
source— 包含用于构建包的源文件列表。 -
sha256sums— 文件校验和,source用于确保构建的可重复性。如果任何文件的校验和发生变化,构建将失败。 -
makedepends— 仅用于构建软件包的依赖项。它们包含在 中.PKGINFO,但在软件包安装过程中不会安装。在本例中,它们是 Go 编译器。 -
函数
build和描述了编译过程以及将编译后的文件放置到目录中。如果需要对程序应用补丁,则在 之前package还会运行一个步骤。preparebuild
让我们在本地编译这个包:
sudo pacman -S git base-devel
cd
git clone https://gitlab.archlinux.org/archlinux/packaging/packages/lazygit
cd lazygit
makepkg -s
ls
我们现在有两个包:
-
lazygit-0.54.0-1-x86_64.pkg.tar.zst— 程序包。 -
lazygit-debug-0.54.0-1-x86_64.pkg.tar.zst— 带有调试符号的包。
您可以通过调用来安装软件包
sudo pacman -U lazygit-*-x86_64.pkg.tar.zst
现在,如果我们输入lazygit,该程序就会打开。要退出,请按Ctrl+C。
出于教学目的,我们从官方仓库中获取了 PKGBUILD 文件——使用 来安装这些文件会更容易pacman -S。但是,如果我们想要安装官方仓库中没有的程序怎么办?这时,了解 PKGBUILD 文件就派上用场了。
传统美食食谱
除了官方仓库之外,还有流行的 Arch 用户仓库。它分发的是 PKBUILD,而不是预构建的软件包,任何人都可以上传。它就像一本社区驱动的食谱。当然,它里面有病毒,但已经被清除了。
AUR 中的每个配方都有自己的 Git 仓库,类似于官方的 GitLab。让我们从那里安装一个软件包yay-bin,然后我会解释它的用途。它不是病毒,但最好阅读它的PKGBUILD文件并亲自了解一下。
cd
git clone https://aur.archlinux.org/yay-bin.git
cd yay-bin
makepkg -si
如您所见,这与从 PKGBUILD 构建常规软件包没有什么不同——它就在那里。提醒一下,AUR 是一个配方仓库,而不是软件包的仓库,并且它没有.db。因此,pacman -Qm您可以使用该命令查看从 AUR 安装的软件包列表。
使用 AUR 的唯一缺点是你必须自己跟踪更新并重新编译软件包。不过社区早就想出了一个解决方案:使用 pacman 封装器来跟踪 AUR 中的软件包。有好几个这样的封装器,其中一个就被yay我们之前安装的软件包调用并包含其中。
要从 AUR 安装另一个包,比如说paru-bin(pacman 的另一个包装器),你现在可以简单地写
yay -S paru-bin
顺便问一下,-bin配方名称是怎么回事?从源代码构建软件包耗时更长,而且更耗资源,所以很多配方都有一个-git从源代码构建的版本和-bin一个使用预构建二进制文件的版本。但这只是一个惯例;你需要阅读 PKGBUILD 文件才能了解软件包的实际构建方式。
该命令yay -Syu不仅yay可以从官方仓库更新软件包,还可以从 AUR 重建更新的软件包。需要注意的是,任何人都可以编写 AUR 中的配方,并且 PKGBUILD 文件很容易包含病毒,因此务必阅读这些文件。
结论
我希望本文能帮助您更好地理解 Arch Linux 打包系统,即:
-
什么是包?里面包含哪些文件?
-
为什么 pacman 需要包数据库以及它是如何工作的?
-
元包和包组之间有什么区别?
-
什么是存储库以及有哪些类型?
-
如何使用镜像分发软件包
-
创建包的配方是什么样的?
-
什么是 AUR?它的缺陷是什么?
祝大家的包包新鲜又安全!
