pacman

来自 ArchWiki
(重定向自 安装理由

pacman 软件包管理器Arch Linux 的主要区别特性之一。它结合了简单的二进制软件包格式和易于使用的 Arch 构建系统pacman 的目标是使管理软件包变得容易,无论它们是来自官方仓库还是用户自己的构建。

Pacman 通过与主服务器同步软件包列表来保持系统最新。这种服务器/客户端模型还允许用户使用简单的命令下载/安装软件包,并附带所有必需的依赖项。

Pacman 使用 C 编程语言编写,并使用 bsdtar(1) tar 格式进行打包。

提示: pacman 软件包包含诸如 makepkgvercmp(8) 等工具。其他有用的工具,如 pactreecheckupdates 可以在 pacman-contrib 中找到(以前pacman 的一部分)。运行 pacman -Ql pacman pacman-contrib | grep -E 'bin/.+' 查看完整列表。

用法

以下只是 pacman 可以执行的操作的一小部分示例。要阅读更多示例,请参阅 pacman(8)

提示: 对于以前使用过其他 Linux 发行版的用户,有一篇有用的 Pacman/Rosetta 文章。

安装软件包

软件包是一个包含以下内容的归档文件

  • 应用程序的所有(已编译)文件
  • 关于应用程序的元数据,例如应用程序名称、版本、依赖项等。
  • pacman 的安装文件和指令

Arch 的软件包管理器 pacman 可以安装、更新和移除这些软件包。使用软件包而不是自己编译和安装程序有多种好处

  • 易于更新:pacman 会在更新可用时立即更新现有软件包
  • 依赖项检查:pacman 为您处理依赖项,您只需指定程序,pacman 会将其与它需要的每个其他程序一起安装
  • 干净移除:pacman 具有软件包中每个文件的列表;这样,当您决定移除软件包时,不会无意中留下任何文件。
注意
  • 软件包通常具有可选依赖项,这些软件包为应用程序提供额外的功能,但不是运行它所严格要求的。安装软件包时,pacman 将列出软件包的可选依赖项,但它们不会在 pacman.log 中找到。使用#查询软件包数据库命令查看软件包的可选依赖项。
  • 当安装一个您仅作为某些其他软件包的(可选)依赖项(即,不是您显式要求的)所需的软件包时,建议使用 --asdeps 选项。有关详细信息,请参阅#安装理由部分。
警告: 在 Arch 中安装软件包时,避免在不升级系统的情况下刷新软件包列表(例如,当在官方仓库中找不到软件包时)。在实践中,不要运行 pacman -Sy package_name 而不是 pacman -Syu package_name,因为这可能导致依赖性问题。请参阅系统维护#部分升级不受支持BBS#89328

安装特定软件包

要安装单个软件包或软件包列表(包括依赖项),请发出以下命令

# pacman -S package_name1 package_name2 ...

要使用正则表达式安装软件包列表(请参阅此论坛帖子

# pacman -S $(pacman -Ssq package_regex)

有时,在不同的仓库(例如 extratesting)中有软件包的多个版本。要安装此示例中 extra 仓库的版本,需要在软件包名称前面定义仓库

# pacman -S extra/package_name

要安装名称中共享相似模式的多个软件包,可以使用花括号展开。例如

# pacman -S plasma-{desktop,mediacenter,nm}

这可以扩展到所需的任意级别

# pacman -S plasma-{workspace{,-wallpapers},pa}
虚拟软件包

虚拟软件包是一种特殊的软件包,它本身不存在,但由一个或多个其他软件包提供。虚拟软件包允许其他软件包不将特定软件包命名为依赖项,以防有多个候选软件包。虚拟软件包不能通过其名称安装,相反,当您安装了提供虚拟软件包的软件包时,它们将安装在您的系统中。一个例子是 dbus-units 软件包。

提示: 当有多个候选软件包时,呈现的选择列表将首先按 仓库pacman.conf 中出现的顺序排序,然后在同一仓库中存在多个结果时按字母顺序排序。

安装软件包组

某些软件包属于可以同时安装的软件包组。例如,发出命令

# pacman -S gnome

将提示您从 gnome 组中选择您要安装的软件包。

有时,软件包组将包含大量软件包,并且可能只有少数几个您想要或不想要安装。不必输入除您不想要的软件包之外的所有数字,有时使用以下语法选择或排除软件包或软件包范围会更方便

Enter a selection (default=all): 1-10 15

这将选择软件包 1 到 10 和 15 进行安装,或者

Enter a selection (default=all): ^5-8 ^2

这将选择除 5 到 8 和 2 之外的所有软件包进行安装。

要查看 gnome 组中包含哪些软件包,请运行

$ pacman -Sg gnome

另请访问 https://archlinux.org.cn/groups/ 以查看可用的软件包组。

注意: 如果列表中的软件包已安装在系统上,即使它已经是最新版本,它也会被重新安装。此行为可以使用 --needed 选项覆盖。

移除软件包

要移除单个软件包,保留其所有依赖项的安装

# pacman -R package_name

要移除软件包及其任何其他已安装软件包都不需要的依赖项

# pacman -Rs package_name
警告: 移除组(例如 gnome)时,这将忽略组中软件包的安装理由,因为它就像组中的每个软件包都单独列出一样。依赖项的安装理由仍然受到尊重。

当移除包含其他所需软件包的组时,上述命令有时可能会拒绝运行。在这种情况下,请尝试

# pacman -Rsu package_name

要移除软件包、其依赖项以及依赖于目标软件包的所有软件包

警告: 此操作是递归的,必须谨慎使用,因为它可能会移除许多潜在需要的软件包。
# pacman -Rsc package_name

要移除另一个软件包所需的软件包,而不移除依赖软件包

警告: 以下操作可能会破坏系统,应避免使用。请参阅 系统维护#避免某些 pacman 命令
# pacman -Rdd package_name

Pacman 在移除某些应用程序时会保存重要的配置文件,并使用扩展名命名它们:.pacsave。要阻止创建这些备份文件,请使用 -n 选项

# pacman -Rn package_name
注意: Pacman 不会移除应用程序本身创建的配置(例如主目录中的“点文件”)。

升级软件包

警告

Pacman 可以仅用一个命令更新系统上的所有软件包。这可能需要相当长的时间,具体取决于系统的最新程度。以下命令同步仓库数据库更新系统的软件包,但不包括配置仓库中没有的“本地”软件包

# pacman -Syu

查询软件包数据库

Pacman 使用 -Q 标志查询本地软件包数据库,使用 -S 标志查询同步数据库,使用 -F 标志查询文件数据库。有关每个标志的相应子选项,请参阅 pacman -Q --helppacman -S --helppacman -F --help

注意: 在查询文件数据库之前同步它以获得最新的结果
# pacman -Fy
提示: 您可以启用/启动 pacman-filesdb-refresh.timer(在 pacman-contrib 软件包中提供)以每周刷新 pacman 文件数据库。

Pacman 可以在数据库中搜索软件包,同时搜索软件包的名称和描述

$ pacman -Ss string1 string2 ...

有时,-s 的内置 ERE(扩展正则表达式)可能会导致大量不需要的结果,因此必须将其限制为仅匹配软件包名称;而不是描述或任何其他字段

$ pacman -Ss '^vim-'

搜索已安装的软件包

$ pacman -Qs string1 string2 ...

在远程软件包中搜索软件包文件名

$ pacman -F string1 string2 ...

显示有关给定软件包的广泛信息(例如,其依赖项)

$ pacman -Si package_name

对于本地安装的软件包

$ pacman -Qi package_name

传递两个 -i 标志也将显示备份文件列表及其修改状态

$ pacman -Qii package_name

检索软件包安装的文件列表

$ pacman -Ql package_name

检索远程软件包安装的文件列表

$ pacman -Fl package_name

验证软件包安装的文件的存在

$ pacman -Qk package_name

第二次传递 k 标志将执行更彻底的检查。

查询数据库以了解文件系统中的文件属于哪个软件包

$ pacman -Qo /path/to/file_name

查询数据库以了解文件属于哪个远程软件包

$ pacman -F /path/to/file_name

列出所有不再作为依赖项需要的软件包(孤立软件包)

$ pacman -Qdt

列出所有显式安装且不需要作为依赖项的软件包

$ pacman -Qet

有关更多示例,请参阅 pacman/技巧和窍门

对于高级功能,请安装 pkgfile,它使用单独的数据库,其中包含所有文件及其关联的软件包。

Pactree

注意: pactree(8) 不再是 pacman 软件包的一部分。相反,它可以在 pacman-contrib 中找到。

查看软件包的依赖树

$ pactree package_name

要查看软件包的依赖树,请将反向标志 -r 传递给 pactree

数据库结构

pacman 数据库通常位于 /var/lib/pacman/sync。对于 /etc/pacman.conf 中指定的每个仓库,都将有一个相应的数据库文件位于此处。数据库文件是 gzipped tar 归档文件,其中包含每个软件包的一个目录,例如 which 软件包

$ tree which-2.21-5
which-2.21-5
|-- desc

desc 文件包含元数据,例如软件包描述、依赖项、文件大小和 MD5 哈希。

清理软件包缓存

Pacman 将其下载的软件包存储在 /var/cache/pacman/pkg/ 中,并且不会自动移除旧版本或已卸载的版本。这有一些优点

  1. 它允许降级软件包,而无需通过其他方式(例如 Arch Linux 归档)检索以前的版本。
  2. 已卸载的软件包可以轻松地直接从缓存目录重新安装,而无需从仓库重新下载。

但是,有必要定期主动清理缓存,以防止目录大小无限增长。

paccache(8) 脚本在 pacman-contrib 软件包中提供,默认情况下,删除已安装和已卸载软件包的所有缓存版本,但最近的三个版本除外

# paccache -r

启用启动 paccache.timer 以每周丢弃未使用的软件包。您可以在 /etc/conf.d/pacman-contrib 中配置服务的参数,例如,对于以下两个示例,使用 PACCACHE_ARGS='-k1'PACCACHE_ARGS='-uk0'

提示: 您可以创建一个钩子,以便在每次 pacman 事务后自动运行此操作,安装 paccache-hookAUR 并查看 其他示例

您还可以定义要保留多少个最近的版本。要仅保留一个过去的版本,请使用

# paccache -rk1

添加 -u/--uninstalled 开关以将 paccache 的操作限制为已卸载的软件包。例如,要删除已卸载软件包的所有缓存版本,请使用以下命令

# paccache -ruk0

有关更多选项,请参阅 paccache -h

Pacman 还具有一些内置选项来清理缓存和不再在配置文件 /etc/pacman.conf 中列出的仓库中的剩余数据库文件。但是 pacman 不提供保留多个过去版本的可能性,因此比 paccache 默认选项更具侵略性。

要移除所有当前未安装的缓存软件包以及未使用的同步数据库,请执行

# pacman -Sc

要从缓存中移除所有文件,请使用两次 clean 开关,这是最具侵略性的方法,并且不会在缓存目录中留下任何内容

# pacman -Scc
警告: 除非迫切需要释放一些磁盘空间,否则应避免从缓存中删除已安装软件包的所有过去版本和所有已卸载的软件包。这将阻止在不再次下载软件包的情况下降级或重新安装软件包。

pkgcachecleanAURpacleanerAUR 是清理缓存的另外两种替代方法。

附加命令

下载软件包而不安装它

# pacman -Sw package_name

安装不是来自远程仓库的“本地”软件包(例如,软件包来自 AUR

# pacman -U /path/to/package/package_name-version.pkg.tar.zst

要在 pacman 的缓存中保留本地软件包的副本,请使用

# pacman -U file:///path/to/package/package_name-version.pkg.tar.zst

安装“远程”软件包(不是来自 pacman 配置文件中声明的仓库)

# pacman -U http://www.example.com/repo/example.pkg.tar.zst

空运行

Pacman 始终列出要安装或移除的软件包,并在采取任何操作之前请求许可。

要获得可处理格式的列表,并阻止 -S-U-R 的操作,可以使用 -p,它是 --print 的缩写。

可以添加 --print-format 以各种方式格式化此列表。 --print-format %n 将返回不带软件包版本的列表。

安装理由

pacman 数据库根据安装理由将已安装的软件包组织成两组

  • 显式安装:字面上通过通用 pacman -S-U 命令传递的软件包;
  • 依赖项:尽管从未(通常)传递给 pacman 安装命令,但隐式安装的软件包,因为它们是显式安装的软件包需要的。

安装软件包时,可以使用以下命令强制将其安装理由设置为依赖项

# pacman -S --asdeps package_name

该命令通常使用,因为显式安装的软件包可能会提供可选软件包,通常用于用户可以自行决定的非必要功能。

提示: 使用 --asdeps 安装可选依赖项将确保,如果您移除孤立软件包pacman 也会移除以此方式设置的可选软件包。

但是,当重新安装软件包时,默认情况下会保留当前的安装理由。

显式安装的软件包列表可以使用 pacman -Qe 显示,而依赖项的补充列表可以使用 pacman -Qd 显示。

要更改已安装软件包的安装理由,请执行

# pacman -D --asdeps package_name

使用 --asexplicit 执行相反的操作。

注意: 不建议在升级时使用 --asdeps--asexplicit 选项,例如使用 pacman -Syu package_name --asdeps。这将更改不仅要安装的软件包的安装理由,还会更改要升级的软件包的安装理由。

软件包安装/升级/移除期间发生了什么

成功时,事务的工作流程遵循五个高级步骤加上事务前/后钩子

  1. 如果没有数据库锁,则初始化事务。
  2. 选择要在事务中添加或移除的软件包。
  3. 根据标志准备事务,方法是对同步数据库、软件包及其依赖项执行健全性检查。
  4. 提交事务
    1. 如果适用,下载软件包 (_alpm_sync_load)。
    2. 如果预先存在的 pacman PreTransaction 钩子适用,则执行它们。
    3. 将移除要替换、冲突或显式目标移除的软件包。
    4. 如果要添加软件包,则提交每个软件包
      1. 如果软件包具有安装脚本,则执行其 pre_install 函数(或升级或移除软件包的情况下的 pre_upgradepre_remove)。
      2. Pacman 删除软件包的先前版本中的所有文件(在升级或移除软件包的情况下)。但是,软件包中标记为配置文件的文件将保留(请参阅/Pacnew 和 Pacsave)。
      3. Pacman 解压软件包并将其文件转储到文件系统中(在安装或升级软件包的情况下)。将覆盖保留的和手动修改的配置文件(请参阅上一步)的文件将以新名称 (.pacnew) 存储。
      4. 如果软件包具有安装脚本,则执行其 post_install 函数(或升级或移除软件包的情况下的 post_upgradepost_remove)。
    5. 如果事务结束时存在的 pacman PostTransaction 钩子适用,则执行它们。
  5. 释放事务和事务资源(即数据库锁)。

配置

Pacman 设置位于 /etc/pacman.conf 中:用户在此处配置程序以所需的方式工作。有关配置文件的深入信息,请参见 pacman.conf(5)

通用选项

通用选项位于 [options] 部分。阅读 pacman.conf(5) 或查看默认的 pacman.conf,以获取有关此处可以执行的操作的信息。

更新前比较版本

要查看可用软件包的旧版本和新版本,请取消注释 /etc/pacman.conf 中的 “VerbosePkgLists” 行。 pacman -Syu 的输出将如下所示

Package (6)             Old Version  New Version  Net Change  Download Size

extra/libmariadbclient  10.1.9-4     10.1.10-1      0.03 MiB       4.35 MiB
extra/libpng            1.6.19-1     1.6.20-1       0.00 MiB       0.23 MiB
extra/mariadb           10.1.9-4     10.1.10-1      0.26 MiB      13.80 MiB

启用并行下载

并行下载(同时)的软件包数量可以使用 /etc/pacman.conf[options] 下的 ParallelDownloads 设置。如果未设置该选项,软件包将按顺序下载。

跳过软件包升级

警告: 跳过软件包时要小心,因为部分升级不受支持。

要在升级系统时跳过特定软件包,请在 [options] 部分中添加此行

IgnorePkg=linux

对于多个软件包,请使用空格分隔的列表,或使用其他 IgnorePkg 行。此外,还可以使用 glob 模式。如果您只想跳过软件包一次,您也可以在命令行上使用 --ignore 选项 - 这次使用逗号分隔的列表。

仍然可以使用 pacman -S 升级忽略的软件包:在这种情况下,pacman 将提醒您这些软件包已包含在 IgnorePkg 语句中。

跳过软件包组升级

警告: 跳过软件包组时要小心,因为部分升级不受支持。

与软件包一样,也可以跳过整个软件包组

IgnoreGroup=gnome

跳过文件升级

使用 NoUpgrade 指令列出的所有文件在软件包安装/升级期间永远不会被触及,并且新文件将使用 .pacnew 扩展名安装。

NoUpgrade=path/to/file

可以像这样指定多个文件

NoUpgrade=path/to/file1 path/to/file2
注意: 该路径引用软件包归档文件中的文件。因此,不要包含前导斜杠。

跳过文件安装到系统

要始终跳过安装特定文件或目录,请在 NoExtract 下列出它们。例如,要避免安装 systemd 单元,请使用此

NoExtract=usr/lib/systemd/system/*

后面的规则会覆盖之前的规则,您可以通过在前面加上 ! 来否定规则。

提示: 当更新软件包时,如果该软件包的语言环境已被 localepurgebleachbit 清除,Pacman 会发出有关缺少语言环境的警告消息。注释掉 pacman.conf 中的 CheckSpace 选项会禁止此类警告,但请考虑空间检查功能将对所有软件包禁用。

维护多个配置文件

如果您有多个配置文件(例如,主配置文件和启用testing 仓库的配置文件),并且必须在配置之间共享选项,则可以使用在配置文件中声明的 Include 选项,例如

Include = /path/to/common/settings

其中 /path/to/common/settings 文件包含两个配置的相同选项。

钩子

Pacman 可以从 /usr/share/libalpm/hooks/ 目录运行事务前和事务后钩子;可以使用 pacman.conf 中的 HookDir 选项指定更多目录,默认为 /etc/pacman.d/hooks。钩子文件名必须以 .hook 为后缀。Pacman 钩子是非交互式的。

例如,Pacman 钩子与 systemd-sysuserssystemd-tmpfiles 结合使用,以便在软件包安装期间自动创建系统用户和文件。例如,tomcat8 指定它需要一个名为 tomcat8 的系统用户以及由此用户拥有的某些目录。当 pacman 确定 tomcat8 包含指定用户和临时文件的文件时,pacman 钩子 systemd-sysusers.hooksystemd-tmpfiles.hook 会调用 systemd-sysuserssystemd-tmpfiles

有关 alpm 钩子的更多信息,请参阅 alpm-hooks(5)

仓库和镜像

除了特殊的 [options] 部分外,pacman.conf 中的每个其他 [section] 都定义了一个要使用的软件包仓库。仓库 是软件包的逻辑集合,这些软件包物理存储在一个或多个服务器上:因此,每个服务器都被称为仓库的镜像

仓库分为 官方仓库非官方用户仓库。配置文件中仓库的顺序很重要;当两个仓库中的软件包具有相同的名称时,列表中靠前的仓库将优先于列表中靠后的仓库,而与版本号无关。为了在使用仓库之前添加它,您需要首先 升级 整个系统。

每个仓库部分都允许直接定义其镜像列表,或通过 Include 指令在专用外部文件中定义;例如,官方仓库的镜像包含在 /etc/pacman.d/mirrorlist 中。有关镜像配置,请参阅 Mirrors 文章。

软件包缓存目录

Pacman 将下载的软件包文件存储在缓存中,该缓存目录在 pacman.conf[options] 部分中由 CacheDir 指定(如果未设置,则默认为 /var/cache/pacman/pkg/)。

即使仅保留已安装软件包的最新版本,缓存目录也可能会随着时间的推移而增长。

如果您想将该目录移动到更方便的位置,请执行以下操作之一

  • pacman.conf 中将 CacheDir 选项设置为新目录。请记住保留尾部斜杠。这是推荐的解决方案
  • /var/cache/pacman/pkg/ 中挂载专用分区或例如 Btrfs 子卷
  • /var/cache/pacman/pkg/ 中绑定挂载选定的目录。
警告: 不要符号链接 /var/cache/pacman/pkg/ 目录到其他位置。这导致 pacman 行为异常,尤其是在 pacman 尝试自我更新时。

软件包安全

Pacman 支持软件包签名,这为软件包增加了一层额外的安全性。默认配置 SigLevel = Required DatabaseOptional 在全局级别为所有软件包启用签名验证。这可以通过每个仓库的 SigLevel 行来覆盖。有关软件包签名和签名验证的更多详细信息,请查看 pacman-key

故障排除

“提交事务失败 (文件冲突)” 错误

如果您看到以下错误: [1]

error: could not prepare transaction
error: failed to commit transaction (conflicting files)
package: /path/to/file exists in filesystem
Errors occurred, no packages were upgraded.

这是因为 pacman 检测到文件冲突,并且按照设计,不会为您覆盖文件。这是设计使然,而不是缺陷。

该问题通常很容易解决 (虽然为了确保安全,您应该尝试找出这些文件最初是如何到达那里的)。一种安全的方法是首先检查另一个软件包是否拥有该文件 (pacman -Qo /path/to/file)。如果该文件由另一个软件包拥有,请 提交错误报告。如果该文件不属于另一个软件包,请重命名“存在于文件系统中”的文件,然后重新发出更新命令。如果一切顺利,则可以删除该文件。

如果您手动安装了一个程序而没有使用 pacman,例如通过 make install,则必须删除/卸载此程序及其所有文件。另请参阅 Pacman 技巧#识别任何软件包未拥有的文件

每个已安装的软件包都提供一个 /var/lib/pacman/local/package-version/files 文件,其中包含有关此软件包的元数据。如果此文件损坏、为空或丢失,则在尝试更新软件包时会导致 file exists in filesystem 错误。这种错误通常只涉及一个软件包。您可以显式运行 pacman -S --overwrite glob package 以强制 pacman 覆盖与 glob 匹配的文件,而不是手动重命名然后删除属于该软件包的所有文件。

警告: 通常避免使用 --overwrite 开关。请参阅 系统维护#避免某些 pacman 命令

“提交事务失败 (无效或损坏的软件包)” 错误

/var/cache/pacman/pkg/ 中查找 .part 文件 (部分下载的软件包) 并删除它们 (通常是由于在 pacman.conf 中使用了自定义的 XferCommand 引起的)。

# find /var/cache/pacman/pkg/ -iname "*.part" -delete

如果 archlinux-keyring 过期,也可能会出现相同的错误,从而阻止 pacman 验证签名。请参阅 Pacman/软件包签名#定期升级系统 了解修复方法以及如何避免将来出现这种情况。

“初始化事务失败 (无法锁定数据库)” 错误

pacman 即将更改软件包数据库时,例如安装软件包,它会在 /var/lib/pacman/db.lck 创建一个锁定文件。这可以防止 pacman 的另一个实例同时尝试更改软件包数据库。

如果 pacman 在更改数据库时被中断,则可能会保留此过时的锁定文件。如果您确定没有 pacman 实例正在运行,请删除锁定文件

# rm /var/lib/pacman/db.lck
提示: 您可以以 root 身份运行 fuser /var/lib/pacman/db.lck 以验证是否有任何进程仍在占用它。

软件包无法在安装时检索

此错误表现为 Not found in sync dbTarget not foundFailed retrieving file

首先,确保软件包确实存在。如果确定软件包存在,则您的软件包列表可能已过期。尝试运行 pacman -Syu 以强制刷新所有软件包列表并升级。另请确保选定的 镜像 是最新的,并且 仓库 配置正确。您还可以使用 Reflector 来保持镜像最新。

也可能是包含该软件包的仓库未在您的系统上启用,例如,该软件包可能在 multilib 仓库中,但 multilib 未在您的 pacman.conf 中启用。

另请参阅 FAQ#为什么在官方仓库中每个共享库只有一个版本?

修复由中断的升级导致系统无法启动

本文或本节的事实准确性存在争议。

原因: 存在多个潜在问题,请参阅讨论页。(在 Talk:Pacman#pacman 在更新期间崩溃的更多细节 中讨论)

无论是由于断电、内核崩溃还是硬件故障,更新都可能被中断。在大多数情况下,不会造成太大损害,但系统很可能无法启动。

  1. 准备一个 USB 闪存安装介质 并启动它。
  2. 挂载 根文件系统。
  3. arch-chroot 进入挂载的根文件系统。
  4. 检查 /var/log/pacman.log 并通过向 pacman -S 提供在失败的事务期间升级的整个软件包列表并允许其重新安装来复制确切的更新,例如
# pacman -S linux linux-headers systemd systemd-libs systemd-sysvcompat firefox texlive-basic texlive-fontsextra texlive-latex texlive-latexextra texlive-latexrecommended texlive-pictures

需要复制确切的升级以确保正确的脚本和小工具能够运行。

Pacman 在升级期间崩溃

如果 pacman 在删除软件包时因“数据库写入”错误而崩溃,并且之后重新安装或升级软件包失败,请执行以下操作

  1. 使用 Arch USB 闪存安装介质 启动。最好使用最新的介质,以便 pacman 版本与系统匹配/更新。
  2. 挂载系统的根文件系统,例如,以 root 身份 mount /dev/sdaX /mnt,并使用 df -h 检查挂载是否有足够的空间
  3. 同时挂载 proc、sys 和 dev 文件系统: mount -t proc proc /mnt/proc; mount --rbind /sys /mnt/sys; mount --rbind /dev /mnt/dev
  4. 如果系统使用默认数据库和目录位置,您现在可以更新系统的 pacman 数据库并通过 pacman --root=/mnt --cachedir=/mnt/var/cache/pacman/pkg -Syu 以 root 身份升级它。
  5. 升级后,一种双重检查未升级但仍然损坏的软件包的方法: find /mnt/usr/lib -size 0
  6. 随后通过 pacman --root /mnt --cachedir=/mnt/var/cache/pacman/pkg -S package 重新安装任何仍然损坏的软件包。

pacman:未找到命令

如果 /var/cache/pacman/pkg 是一个符号链接,pacman 将尝试创建一个目录来代替,因此在自我升级期间删除此符号链接。这将导致更新失败。结果,pacman 软件包的 /usr/bin/pacman 和其他内容将丢失。

永远不要符号链接 /var/cache/pacman/pkg,因为它由 pacman 控制。请改用 CacheDir 选项或绑定挂载;请参阅 #软件包缓存目录

如果您已经遇到此问题并破坏了您的系统,您可以手动从软件包中提取 /usr 内容以恢复 pacman,然后正确地重新安装它;请参阅 FS#73306相关论坛帖子 以了解详细信息。

手动重新安装 pacman

使用 pacman-static

pacman-staticAURpacman 的静态编译版本,因此即使系统上的库无法正常工作,它也能够运行。当执行了 部分升级 并且 pacman 无法再运行时,这也可能会派上用场。

置顶评论和 PKGBUILD 提供了一种直接下载二进制文件的方法,该二进制文件可用于重新安装 pacman 或在部分升级的情况下升级整个系统。

使用外部 pacman

如果即使 pacman-static 也不起作用,则可以使用外部 pacman 进行恢复。最简单的方法之一是使用 archiso 并简单地使用 --sysroot--root 来指定系统挂载点以执行操作。有关如何挂载 --sysroot 所需的必要文件系统,请参阅 Chroot#使用 chroot

通过手动提取

警告: 使用此方法非常容易使您的系统变得更糟。仅当 #Pacman 在升级期间崩溃 中的方法不是一种选择时,才将其作为最后的手段使用。

即使 pacman 严重损坏,您也可以通过下载最新的软件包并将它们提取到正确的位置来手动修复它。要执行的大致步骤是

  1. 确定要安装的 pacman 依赖项
  2. 从您选择的 镜像 下载每个软件包
  3. 将每个软件包提取到根目录
  4. 使用 pacman -S --overwrite 重新安装这些软件包,以相应地更新软件包数据库
  5. 执行完整的系统升级

如果您手边有一个健康的 Arch 系统,您可以使用以下命令查看完整的依赖项列表

$ pacman -Q $(pactree -u pacman)

但您可能只需要更新其中的一些,具体取决于您的问题。提取软件包的一个示例是

# tar -xvpwf package.tar.zst -C / --exclude .PKGINFO --exclude .INSTALL --exclude .MTREE --exclude .BUILDINFO

请注意交互模式下 w 标志的用法。以非交互方式运行非常危险,因为您最终可能会覆盖重要的文件。还要注意以正确的顺序提取软件包 (即首先提取依赖项)。 此论坛帖子 包含此过程的示例,其中只有几个 pacman 依赖项损坏。

重启后出现 “找不到根设备” 错误

最有可能的是,initramfs内核 更新期间损坏 (不正确地使用 pacman--overwrite 选项可能是原因)。有两种选择;首先,尝试 Fallback 条目。

提示: 如果您删除了 Fallback 条目,您可以始终在引导加载程序菜单出现时按 Tab 键 (对于 Syslinux) 或 e 键 (对于 GRUB 或 systemd-boot),将其重命名为 initramfs-linux-fallback.img,然后按 Enterb 键 (取决于您的 引导加载程序) 以使用新参数启动。

一旦系统启动,请从控制台或终端运行以下命令 (对于默认的 linux 内核) 以重建 initramfs 映像

# mkinitcpio -p linux

如果这不起作用,请从当前的 Arch 发行版 (CD/DVD 或 USB 闪存盘) 挂载 您的根分区和引导分区到 /mnt/mnt/boot。然后使用 arch-chroot chroot

# arch-chroot /mnt
# pacman -Syu mkinitcpio systemd linux
注意
  • 如果您没有当前的发行版,或者您只有一些其他 “live” Linux 发行版,您可以使用老式方法 chroot。显然,键入的内容将比简单地运行 arch-chroot 脚本要多。
  • 如果 pacmanCould not resolve host 而失败,请 检查您的互联网连接
  • 如果您无法进入 arch-chroot 或 chroot 环境,但需要重新安装软件包,您可以使用命令 pacman --sysroot /mnt -Syu foo bar 在您的根分区上使用 pacman

重新安装内核 (linux 软件包) 将使用 mkinitcpio -p linux 自动重新生成 initramfs 映像。无需单独执行此操作。

之后,建议您运行 exitumount /mnt/{boot,} reboot

“警告:当前区域设置无效;使用默认的 "C" 区域设置” 错误

正如错误消息所说,您的区域设置配置不正确。请参阅 Locale

Pacman 不遵守代理设置

确保已设置相关的环境变量 ($http_proxy$ftp_proxy 等)。如果您将 pacmansudo 一起使用,则需要配置 sudo 以 将这些环境变量传递给 pacman。此外,请确保 dirmngr 的配置在 /etc/pacman.d/gnupg/dirmngr.conf 中具有 honor-http-proxy,以便在刷新密钥时遵守代理。

如何重新安装所有软件包,同时保留有关某些软件包是显式安装还是作为依赖项安装的信息?

要重新安装所有原生软件包: pacman -Qnq | pacman -S -pacman -S $(pacman -Qnq) (默认情况下,-S 选项保留安装原因)。

然后,您需要重新安装所有外部软件包,可以使用 pacman -Qmq 列出这些软件包。

“无法打开共享对象文件” 错误

看起来之前的 pacman 事务删除了或损坏了 pacman 本身所需的共享库。

要从这种情况中恢复,您需要手动将所需的库解压缩到您的文件系统中。首先找到哪个软件包包含丢失的库,然后在 pacman 缓存 (/var/cache/pacman/pkg/) 中找到它。将所需的共享库解压缩到文件系统。这将允许运行 pacman

现在您需要重新安装损坏的软件包。请注意,您需要使用 --overwrite 标志,因为您刚刚解压缩了系统文件,而 pacman 不知道这一点。Pacman 将使用软件包中的文件正确替换我们的共享库文件。

就是这样。更新系统的其余部分。

软件包下载冻结

已经报告了一些关于网络问题的报告,这些问题阻止 pacman 更新/同步仓库。 [2] [3] 当原生安装 Arch Linux 时,通过将默认的 pacman 文件下载器替换为替代方案来解决这些问题 (有关更多详细信息,请参阅 提高 pacman 性能)。当在 VirtualBox 中将 Arch Linux 作为访客操作系统安装时,通过在机器属性中使用 Host interface 而不是 NAT 也解决了此问题。

从镜像检索文件 'core.db' 失败

如果您收到此错误消息并且 镜像 正确,请尝试设置不同的 名称服务器

错误:'local-package.pkg.tar': 权限被拒绝

如果您想在 sshfs 挂载上使用 pacman -U 安装软件包并收到此错误,请将软件包移动到本地目录并再次尝试安装。

错误:无法确定 cachedir 挂载点 /var/cache/pacman/pkg

在 chroot 环境中执行例如 pacman -Syu 时,遇到错误

error: could not determine cachedir mount point /var/cache/pacman/pkg
error: failed to commit transaction (not enough free disk space)

这通常是由于 chroot 目录在进入 chroot 时不是挂载点引起的。有关解决方案,请参阅 从现有 Linux 安装 Arch Linux#下载基本工具 中的注释,以及 arch-chroot(8) 以获得解释和使用绑定挂载使 chroot 目录成为挂载点的示例。

error: GPGME error: No data

如果您无法更新软件包并收到此错误,请在尝试更新之前尝试 rm -r /var/lib/pacman/sync/

如果删除同步文件没有帮助,请在使用 file /var/lib/pacman/sync/* 尝试更新之前检查同步文件是否为 gzip compressed data。路由器或代理可能会损坏下载。

如果同步文件类型正确,则可能是镜像服务器有问题。使用 pacman-conf -r corepacman-conf -r extra 查找正在使用的镜像服务器。将返回的第一个 url 粘贴到浏览器中,并检查是否返回了文件列表。如果镜像返回错误,请在 /etc/pacman.d/mirrorlist 中注释掉它。

错误:GPGME 错误:一般错误和 ":: 文件 /var/cache/pacman/pkg/<package>.pkg.tar.zst 已损坏 (无效或损坏的软件包 (PGP 签名))。"

如果发生此错误,并且您例如无法更新系统或任何软件包,则可能是您将 DISPLAY 设置为空白值,这似乎会破坏 GPG-Flow。

在这种情况下,unset DISPLAY 或将其设置为任意值很可能会再次允许更新,以防上述任何选项尚未奏效。有关更多详细信息,请参阅 帖子。

重新安装损坏或不同步的软件包

可以使用 pacman -Qk $pkg 检查 $pkg 软件包的已安装文件是否与其数据库版本中的文件匹配。对于多个软件包,可以使用以下循环重新安装所有缺少文件的软件包

# LC_ALL=C.UTF-8 pacman -Qk 2>/dev/null | grep -v ' 0 missing files' | cut -d: -f1 |
    while read -r package; do
        pacman -S "$package" --noconfirm
    done

假设您的本地数据库 (位于 /var/lib/pacman 中) 比 / 文件系统中的已安装软件包更新 (例如,由于部分回滚),那么此方法是使根文件系统与本地数据库重新同步的合适方法。

另请参阅