跳转至内容

pacman

来自 ArchWiki
(从 Pacman.conf 重定向而来)

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,因为这可能导致依赖问题。请参阅 System maintenance#Partial upgrades are unsupportedBBS#89328

安装特定软件包

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

# pacman -S package_name1 package_name2 ...

使用正则表达式安装一系列软件包(参见 此论坛帖子

# pacman -S $(pacman -Ssq package_regex)

有时,不同的仓库(例如 extraextra-testing)中会有同一软件包的多个版本。例如,要安装 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

要移除一个被其他软件包需要的软件包,而又不移除依赖该软件包的软件包

警告 以下操作可能会破坏系统,应避免使用。请参阅 System maintenance#Avoid certain pacman commands
# 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/Tips and tricks

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

Pactree

注意 pactree(8) 不再是 pacman 包的一部分。而是可以在 pacman-contrib 中找到。

查看软件包的依赖树

$ pactree package_name

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

数据库结构

pacman 数据库通常位于 /var/lib/pacman/sync。对于 /etc/pacman.conf 中指定的每个仓库,在那里都会有一个对应的数据库文件。数据库文件是压缩的 tar 存档,其中包含每个软件包的一个目录,例如 which 软件包

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

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

清理软件包缓存

Pacman 将下载的软件包存储在缓存中,位于 /var/cache/pacman/pkg/ 目录,并且不会自动删除旧版本或未安装的版本。这有一些好处

  1. 它允许 降级软件包,而无需通过其他方式(如 Arch Linux Archive)获取前一个版本。
  2. 已卸载的软件包可以很容易地直接从缓存目录重新安装,而无需从仓库重新下载。

然而,有必要定期清理缓存,以防止目录无限增长。

paccache.script,包含在 pacman-contrib 包中,默认删除已安装和未安装软件包的所有缓存版本,但保留最近的三个

# paccache -r

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

提示 您可以创建一个 hook 来在每次 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。这将改变被安装软件包以及被升级软件包的安装原因。

软件包安装/升级/移除时发生什么

成功时,事务的工作流程包括五个高级步骤以及事务前/后的 hook

  1. 如果数据库没有被锁定,则初始化事务。
  2. 选择将在事务中添加或删除的软件包。
  3. 基于标志准备事务,对同步数据库、软件包及其依赖项执行健全性检查。
  4. 提交事务
    1. 如果适用,下载软件包(_alpm_sync_load)。
    2. 如果存在 pacman PreTransaction hook,则执行它们。
    3. 移除将被替换、冲突或明确目标为移除的软件包。
    4. 如果存在要添加的软件包,则提交每个软件包
      1. 如果软件包有安装脚本,则执行其 pre_install 函数(或在升级或移除软件包的情况下为 pre_upgradepre_remove)。
      2. pacman 删除软件包先前版本的(在升级或移除软件包的情况下)所有文件。但是,标记为软件包配置文件(参见 /Pacnew and Pacsave)的文件将被保留。
      3. pacman 解压软件包并将其文件转储到文件系统(在安装或升级软件包的情况下)。覆盖已保留的、手动修改的配置文件(参见上一步)的文件将被保存为新名称(.pacnew)。
      4. 如果软件包有安装脚本,则执行其 post_install 函数(或在升级或移除软件包的情况下为 post_upgradepost_remove)。
    5. 如果存在位于事务末尾的 pacman PostTransaction hook,则执行它们。
  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 选项进行配置。随 pacman 包附带的 /etc/pacman.conf 将其设置为 5。如果未设置该选项,软件包将按顺序下载。

跳过软件包升级

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

要使特定软件包在 升级系统时被跳过,请在 [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 下。例如,要避免安装 bash 补全脚本,请使用

NoExtract=usr/share/bash-completion/completions/*

后续规则覆盖先前的规则,并且可以通过在前面添加 ! 来否定一个规则。

维护多个配置文件

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

Include = /path/to/common/settings

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

钩子

pacman 可以从 /usr/share/libalpm/hooks/ 目录运行事务前和事务后的 hook。可以使用 pacman.conf 中的 HookDir 选项指定更多目录,该选项默认为 /etc/pacman.d/hooks。Hook 文件名必须以 .hook 为后缀。pacman hook 不支持交互。

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

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

仓库和镜像

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

仓库分为 官方非官方。配置文件中仓库的顺序很重要;当两个仓库中的软件包名称相同时,先列出的仓库将优先于后面列出的仓库,无论版本号如何。要使用某个仓库,在添加它之后,您需要先 升级整个系统。

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

软件包缓存目录

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

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

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

  • CacheDir 选项在 pacman.conf 中设置为新目录。请记住保留末尾的斜杠。**这是推荐的解决方案**。
  • /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 文件,其中包含有关该软件包的元数据。如果此文件损坏、为空或丢失,则在尝试更新软件包时会导致“文件在文件系统中存在”的错误。此类错误通常只涉及一个软件包。您可以通过显式运行 pacman -S --overwrite glob package 来强制 pacman 覆盖与 glob 匹配的文件,而不是手动重命名并稍后删除属于该软件包的所有文件。

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

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

本文或本章节已过时。

原因: 从 pacman 7.1.0 开始,过期的密钥应自动获取更新(可靠性取决于密钥基础设施...) - 这应该会消除需要更新密钥时出现的“软件包损坏”消息。(在 Talk:Pacman 中讨论)

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

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

如果 archlinux-keyring 过期,阻止 pacman 验证签名,也可能出现相同的错误。有关修复方法和如何避免此问题,请参阅 Pacman/Package signing#定期升级系统

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

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 来保持镜像最新。

如果 pacman 报告没有可更新的内容,但仍继续显示 Failed retrieving file 错误,请考虑使用 pacman -Syyu 强制下载数据库。在正常情况下不需要这样做,所以请更仔细地检查 镜像的状态和一致性

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

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

修复因升级中断而无法引导的系统

本文章或章节需要扩充。

原因: 需要考虑多方面因素。(在 Talk:Pacman#pacman 在更新期间崩溃的更多细节 中讨论)

无论是由于断电、内核恐慌还是硬件故障,升级都可能中断。在大多数情况下,损害不会太大,但系统很可能无法引导。

  1. 准备一个 USB 闪存安装介质并启动它。
  2. 挂载根文件系统以及您的 ESP
  3. 使用 arch-chroot 进入挂载的根文件系统。
  4. 检查 /var/log/pacman.log 并通过将失败事务期间升级的全部软件包列表提供给 pacman -Syu 来复制确切的升级,使其在恢复原始升级时重新安装。
# pacman -Syu $(grep "\[2025-07-27T22.*\] \[ALPM\] upgraded" /var/log/pacman.log | cut -d " " -f4 | tr "\n" " ")

复制确切的升级是必要的,以确保正确的脚本和钩子会运行。

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. 如果系统使用默认的数据库和目录位置,您现在可以通过 root 运行 pacman --root=/mnt --cachedir=/mnt/var/cache/pacman/pkg -Syu 来更新系统的 pacman 数据库并升级它。
  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 或升级整个系统。

在 PKGBUILD 构建失败时使用预编译的 pacman-static 二进制文件

在某些情况下,您的系统可能过于损坏而无法运行 makepkg 或构建 pacman-staticAUR 软件包(例如,由于缺少或不兼容的库)。在这种情况下,您可以从可信赖的来源下载预编译的 pacman-static 二进制文件。此静态二进制文件不依赖于系统库,可用于恢复您系统上工作的 pacman

二进制文件的可靠来源是:

# https://pkgbuild.com/~morganamilo/pacman-static/x86_64/bin/pacman-static

要使用它,请运行:

$ curl -L -o pacman-static https://pkgbuild.com/~morganamilo/pacman-static/x86_64/bin/pacman-static
$ chmod +x pacman-static
$ sudo ./pacman-static -Syu pacman

这将更新您的系统并重新安装 pacman,修复与缺少共享库相关的损坏的依赖关系。

使用外部 pacman

即使 pacman-static 也不起作用,也有可能使用外部 pacman 进行恢复。其中一种最简单的方法是使用 archiso,只需使用 --sysroot--root 指定系统挂载点即可执行操作。参阅 Chroot#使用 chroot 以了解如何挂载 --sysroot 所需的文件系统。

通过手动解压

警告 使用此方法极易使您的系统状况更糟。仅在 #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 条目,在启动加载器菜单显示时(对于 Syslinux),您可以始终按 Tab 键,或(对于 GRUB 或 systemd-boot)按 e,将其重命名为 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 脚本要输入更多内容。
  • 如果 pacman 出现 Could not resolve host 错误,请检查您的互联网连接
  • 如果您无法进入 arch-chroot 或 chroot 环境但需要重新安装软件包,可以使用命令 pacman --sysroot /mnt -Syu foo bar 来对您的根分区使用 pacman

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

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

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

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

缺少区域设置警告消息

当区域设置文件被诸如 bleachbitlocalepurgeAUR 等工具故意删除时,pacman 在软件包更新期间可能会发出关于缺少区域设置的警告。

要抑制这些警告,您可以注释掉 pacman.conf 中的 CheckSpace 选项。请记住,禁用 CheckSpace 会关闭所有软件包安装的空间检查功能,因此请仅在您有其他方法监控磁盘空间时使用此解决方法。

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 性能)解决了这些问题。在将 Arch Linux 安装为 VirtualBox 的访客操作系统时,也通过在虚拟机属性中使用 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 目录成为挂载点的示例。

错误:GPGME 错误:无数据

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

如果删除 sync 文件无济于事,请使用 file /var/lib/pacman/sync/* 检查 sync 文件是否为 gzip compressed data,然后再尝试更新。路由器或代理可能会损坏下载。损坏可能表现为 HTML 类型。

如果 sync 文件类型正确,则可能是镜像服务器有问题。使用 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,并且比 / 文件系统中的已安装软件包更新(例如,由于部分回滚),那么此方法是使根文件系统与本地数据库重新同步的合适方法。

参见