pacman
pacman 软件包管理器 是 Arch Linux 的主要区别性特征之一。它将简单的二进制软件包格式与易于使用的 Arch 构建系统 相结合。pacman 的目标是使软件包管理变得容易,无论它们是来自 官方仓库 还是用户自己的构建。
Pacman 通过与主服务器同步软件包列表来保持系统更新。这种服务器/客户端模型还允许用户使用简单的命令下载/安装软件包,并附带所有必需的依赖项。
Pacman 使用 C 编程语言编写,并使用 bsdtar(1) tar 格式进行打包。
pacman -Ql pacman pacman-contrib | grep -E 'bin/.+'
以查看完整列表。用法
以下只是 pacman 可以执行的操作的一小部分示例。要阅读更多示例,请参阅 pacman(8)。
安装软件包
软件包是一个包含以下内容的压缩文件:
- 应用程序的所有(已编译)文件
- 有关应用程序的元数据,例如应用程序名称、版本、依赖项等。
- pacman 的安装文件和指令
Arch 的软件包管理器 pacman 可以安装、更新和移除这些软件包。使用软件包而不是自己编译和安装程序有多种好处:
- 易于更新:pacman 将在更新可用时立即更新现有软件包
- 依赖项检查:pacman 为您处理依赖项,您只需指定程序,pacman 就会将其与所需的其他所有程序一起安装
- 干净移除:pacman 具有软件包中每个文件的列表;这样,当您决定移除软件包时,不会意外留下任何文件。
pacman -Sy package_name
而不是 pacman -Syu package_name
,因为这可能会导致依赖性问题。请参阅 系统维护#不支持部分升级 和 BBS#89328。安装特定软件包
要安装单个软件包或软件包列表(包括依赖项),请发出以下命令
# pacman -S package_name1 package_name2 ...
要使用正则表达式安装软件包列表(请参阅 此论坛帖子)
# pacman -S $(pacman -Ssq package_regex)
有时,不同仓库(例如,extra 和 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
当移除包含其他所需软件包的组时,上述命令有时可能拒绝运行。在这种情况下,请尝试
# pacman -Rsu package_name
要移除软件包、其依赖项以及所有依赖于目标软件包的软件包
# pacman -Rsc package_name
要移除另一个软件包所需的软件包,而不移除依赖软件包
# pacman -Rdd package_name
Pacman 在移除某些应用程序时会保存重要的配置文件,并使用扩展名命名它们:.pacsave。要阻止创建这些备份文件,请使用 -n
选项
# pacman -Rn package_name
升级软件包
- 用户应遵循 系统维护#升级系统 部分中的指南定期升级其系统,而不是盲目运行以下命令。
- Arch 仅支持完整系统升级。有关详细信息,请参阅 系统维护#不支持部分升级 和 #安装软件包。
Pacman 可以使用一个命令更新系统上的所有软件包。这可能需要相当长的时间,具体取决于系统的最新程度。以下命令同步仓库数据库并更新系统的软件包,排除配置的仓库中没有的“本地”软件包
# pacman -Syu
查询软件包数据库
Pacman 使用 -Q
标志查询本地软件包数据库,使用 -S
标志查询同步数据库,使用 -F
标志查询文件数据库。有关每个标志的相应子选项,请参阅 pacman -Q --help
、pacman -S --help
和 pacman -F --help
。
# pacman -Fy
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 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/
中,并且不会自动移除旧版本或已卸载的版本。这有一些优点:
- 它允许降级软件包,而无需通过其他方式(例如 Arch Linux 归档)检索以前的版本。
- 可以轻松地直接从缓存目录重新安装已卸载的软件包,而无需从仓库重新下载。
但是,有必要定期清理缓存,以防止目录大小无限增长。
paccache(8) 脚本(在 pacman-contrib 软件包中提供)默认情况下删除已安装和已卸载软件包的所有缓存版本,但保留最近的三个版本
# paccache -r
启用 和 启动 paccache.timer
以每周丢弃未使用的软件包。您可以在 /etc/conf.d/pacman-contrib
中配置服务的参数,例如,对于以下两个示例,使用 PACCACHE_ARGS='-k1'
或 PACCACHE_ARGS='-uk0'
。
您还可以定义要保留多少个最近的版本。要仅保留一个过去的版本,请使用
# paccache -rk1
添加 -u
/--uninstalled
开关以将 paccache 的操作限制为已卸载的软件包。例如,要移除已卸载软件包的所有缓存版本,请使用以下命令
# paccache -ruk0
有关更多选项,请参阅 paccache -h
。
Pacman 还具有一些内置选项,用于清理缓存和不再在配置文件 /etc/pacman.conf
中列出的仓库的剩余数据库文件。但是,pacman 不提供保留过去版本数量的可能性,因此比 paccache 默认选项更激进。
要移除所有未当前安装的缓存软件包和未使用的同步数据库,请执行
# pacman -Sc
要移除缓存中的所有文件,请使用两次 clean 开关,这是最激进的方法,缓存目录中将不留下任何内容
# pacman -Scc
pkgcachecleanAUR 和 pacleanerAUR 是清理缓存的另外两种替代方案。
附加命令
下载软件包而不安装它
# 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
。这不仅会更改正在安装的软件包的安装理由,还会更改正在升级的软件包的安装理由。软件包安装/升级/移除期间发生了什么
如果成功,事务的工作流程遵循五个高级步骤加上事务前/后钩子:
- 如果不存在数据库锁,则初始化事务。
- 选择将在事务中添加或移除的软件包。
- 通过对同步数据库、软件包及其依赖项执行健全性检查,根据标志准备事务。
- 提交事务
- 如果适用,下载软件包 (
_alpm_sync_load
)。 - 如果存在预先存在的 pacman
PreTransaction
钩子适用,则执行它们。 - 移除要替换、冲突或显式目标移除的软件包。
- 如果有要添加的软件包,则提交每个软件包
- 如果软件包有安装脚本,则执行其
pre_install
函数(或升级或移除软件包的情况下的pre_upgrade
或pre_remove
)。 - Pacman 删除软件包先前版本的所有文件(在升级或移除软件包的情况下)。但是,在软件包中标记为配置文件的文件将被保留(请参阅 /Pacnew 和 Pacsave)。
- Pacman 解压软件包并将其文件转储到文件系统中(在安装或升级软件包的情况下)。将覆盖保留的且手动修改的配置文件(请参阅上一步)的文件将使用新名称 (.pacnew) 存储。
- 如果软件包有安装脚本,则执行其
post_install
函数(或升级或移除软件包的情况下的post_upgrade
或post_remove
)。
- 如果软件包有安装脚本,则执行其
- 如果事务结束时存在的 pacman
PostTransaction
钩子适用,则执行它们。
- 如果适用,下载软件包 (
- 释放事务和事务资源(即数据库锁)。
配置
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/*
后面的规则会覆盖之前的规则,您可以通过在前面加上 !
来否定规则。
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-sysusers
和 systemd-tmpfiles
结合使用,以便在软件包安装期间自动创建系统用户和文件。例如,tomcat8 指定它需要一个名为 tomcat8
的系统用户以及由此用户拥有的某些目录。当 pacman 确定 tomcat8 包含指定用户和 tmp 文件的文件时,pacman 钩子 systemd-sysusers.hook
和 systemd-tmpfiles.hook
会调用 systemd-sysusers
和 systemd-tmpfiles
。
有关 alpm 钩子的更多信息,请参阅 alpm-hooks(5)。
仓库和镜像
除了特殊的 [options] 部分之外,pacman.conf
中的每个其他 [section]
都定义了一个要使用的软件包仓库。仓库是软件包的逻辑集合,它们物理存储在一个或多个服务器上:因此,每个服务器都称为仓库的镜像。
仓库分为官方仓库和非官方仓库。配置文件中仓库的顺序很重要;当两个仓库中的软件包具有相同的名称时,列表中首先列出的仓库将优先于文件中稍后列出的仓库,而与版本号无关。为了在使用仓库之前添加它,您需要首先升级整个系统。
每个仓库部分都允许直接定义其镜像列表,或者通过 Include
指令在专用的外部文件中定义;例如,官方仓库的镜像包含在 `/etc/pacman.d/mirrorlist` 中。有关镜像配置,请参阅镜像文章。
软件包缓存目录
Pacman 将下载的软件包文件存储在缓存中,目录由 `pacman.conf` 的 [options] 部分中的 `CacheDir` 指定(如果未设置,则默认为 `/var/cache/pacman/pkg/`)。
即使只保留最新版本的已安装软件包,缓存目录也可能会随着时间的推移而增长。
如果您想将该目录移动到更方便的位置,请执行以下操作之一
- 在 `pacman.conf` 中将 `CacheDir` 选项设置为新目录。记住保留尾部斜杠。这是推荐的解决方案。
- 在 `/var/cache/pacman/pkg/` 中挂载专用分区或例如 Btrfs 子卷。
- 在 `/var/cache/pacman/pkg/` 中绑定挂载选定的目录。
软件包安全
Pacman 支持软件包签名,这为软件包增加了一层额外的安全性。默认配置 `SigLevel = Required DatabaseOptional` 在全局级别为所有软件包启用签名验证。这可以被每个仓库的 `SigLevel` 行覆盖。有关软件包签名和签名验证的更多详细信息,请查看pacman-key。
故障排除
“Failed to commit transaction (conflicting files)” 错误
如果您看到以下错误: [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 tips#识别任何软件包未拥有的文件。
每个已安装的软件包都提供一个 `/var/lib/pacman/local/package-version/files` 文件,其中包含有关此软件包的元数据。如果此文件损坏、为空或丢失,则在尝试更新软件包时会导致 `file exists in filesystem` 错误。这样的错误通常只涉及一个软件包。您可以显式运行 `pacman -S --overwrite glob package` 以强制 pacman 覆盖与 `glob` 匹配的文件,而不是手动重命名然后删除属于相关软件包的所有文件。
“Failed to commit transaction (invalid or corrupted package)” 错误
在 `/var/cache/pacman/pkg/` 中查找 .part 文件(部分下载的软件包)并删除它们(通常是由在 `pacman.conf` 中使用自定义 `XferCommand` 引起的)。
# find /var/cache/pacman/pkg/ -iname "*.part" -delete
如果 archlinux-keyring 过期,阻止 pacman 验证签名,也可能出现同样的错误。请参阅Pacman/Package signing#定期升级系统以获取修复方法以及如何在将来避免这种情况。
“Failed to init transaction (unable to lock database)” 错误
当 pacman 要更改软件包数据库时,例如安装软件包,它会在 `/var/lib/pacman/db.lck` 创建一个锁文件。这防止了 pacman 的另一个实例同时尝试更改软件包数据库。
如果 pacman 在更改数据库时中断,则可能会保留此过时的锁文件。如果您确定没有 pacman 实例正在运行,则删除锁文件
# rm /var/lib/pacman/db.lck
软件包在安装时无法检索
此错误表现为 `Not found in sync db`、`Target not found` 或 `Failed retrieving file`。
首先,确保软件包实际存在。如果确定软件包存在,则您的软件包列表可能已过期。尝试运行 `pacman -Syu` 以强制刷新所有软件包列表并升级。还要确保选定的镜像是最新的,并且仓库配置正确。您还可以使用Reflector来保持镜像最新。
也可能是包含软件包的仓库未在您的系统上启用,例如,该软件包可能在 multilib 仓库中,但 multilib 未在您的 `pacman.conf` 中启用。
另请参阅FAQ#为什么在官方仓库中每个共享库只有一个版本?。
修复由升级中断导致系统无法启动的问题
无论是由于断电、内核崩溃还是硬件故障,更新都可能被中断。在大多数情况下,不会有太多损坏,但系统很可能无法启动。
- 准备一个USB 闪存安装介质并启动它。
- 挂载根文件系统。
- `arch-chroot` 进入挂载的根文件系统。
- 检查 `/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
需要复制确切的升级以确保正确的 scriptlet 和钩子将运行。
Pacman 在升级期间崩溃
如果 pacman 在删除软件包时因“数据库写入”错误而崩溃,并且此后重新安装或升级软件包失败,请执行以下操作
- 使用 Arch USB 闪存安装介质启动。最好使用最新的介质,以便 pacman 版本与系统版本匹配/更新。
- 挂载系统的根文件系统,例如,以 root 身份挂载 `mount /dev/sdaX /mnt`,并使用 `df -h` 检查挂载是否有足够的空间
- 同时挂载 proc、sys 和 dev 文件系统:`mount -t proc proc /mnt/proc; mount --rbind /sys /mnt/sys; mount --rbind /dev /mnt/dev`
- 如果系统使用默认数据库和目录位置,您现在可以以 root 身份通过 `pacman --root=/mnt --cachedir=/mnt/var/cache/pacman/pkg -Syu` 更新系统的 pacman 数据库并升级它。
- 或者,如果您无法更新/升级,请参阅Pacman/Tips and tricks#重新安装所有软件包。
- 升级后,一种双重检查未升级但仍然损坏的软件包的方法:`find /mnt/usr/lib -size 0`
- 之后,通过 `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-staticAUR 是 pacman 的静态编译版本,因此即使系统上的库无法正常工作,它也能够运行。当执行部分升级并且 pacman 无法再运行时,这也可能派上用场。
固定的评论和 PKGBUILD 提供了一种直接下载二进制文件的方法,该二进制文件可用于重新安装 pacman 或在部分升级的情况下升级整个系统。
使用外部 pacman
如果即使 `pacman-static` 也不起作用,则可以使用外部 pacman 进行恢复。最简单的方法之一是使用 archiso,只需使用 `--sysroot` 或 `--root` 来指定系统的挂载点以执行操作。请参阅 Chroot#使用 chroot,了解如何挂载 `--sysroot` 所需的必要文件系统。
通过手动提取
即使 pacman 严重损坏,您也可以通过手动下载最新的软件包并将它们解压到正确的位置来修复它。要执行的粗略步骤是
- 确定要安装的 pacman 依赖项
- 从您选择的镜像下载每个软件包
- 将每个软件包解压到 root
- 使用 `pacman -S --overwrite` 重新安装这些软件包,以相应地更新软件包数据库
- 执行完整的系统升级
如果您手头有一个健康的 Arch 系统,您可以使用以下命令查看完整的依赖项列表
$ pacman -Q $(pactree -u pacman)
但您可能只需要更新其中的一些,具体取决于您的问题。解压软件包的一个例子是
# tar -xvpwf package.tar.zst -C / --exclude .PKGINFO --exclude .INSTALL --exclude .MTREE --exclude .BUILDINFO
请注意使用 `w` 标志进行交互模式。非交互式运行非常危险,因为您最终可能会覆盖重要的文件。还要注意以正确的顺序解压软件包(即,先解压依赖项)。此论坛帖子包含此过程的示例,其中只有几个 pacman 依赖项被破坏。
重启后出现“Unable to find root device”错误
最有可能的是,initramfs 在 kernel 更新期间损坏(不当使用 pacman 的 `--overwrite` 选项可能是原因)。有两种选择;首先,尝试 Fallback 条目。
系统启动后,从控制台或终端运行此命令(对于 stock linux 内核),以重建 initramfs 镜像
# mkinitcpio -p linux
如果这不起作用,请从当前的 Arch 版本(CD/DVD 或 USB 驱动器)挂载您的根分区和引导分区到 `/mnt` 和 `/mnt/boot`。然后使用 arch-chroot chroot
# arch-chroot /mnt # pacman -Syu mkinitcpio systemd linux
重新安装内核(linux 软件包)将使用 `mkinitcpio -p linux` 自动重新生成 initramfs 镜像。无需单独执行此操作。
之后,建议您运行 `exit`、`umount /mnt/{boot,}` 和 `reboot`。
“Warning: current locale is invalid; using default "C" locale” 错误
正如错误消息所说,您的区域设置未正确配置。请参阅区域设置。
Pacman 不遵守代理设置
确保相关的环境变量(`$http_proxy`、`$ftp_proxy` 等)已设置。如果您将 pacman 与 sudo 一起使用,则需要配置 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 作为访客操作系统安装时,此问题也通过在机器属性中使用主机接口而不是 NAT 来解决。
从镜像检索文件 'core.db' 失败
如果您收到此错误消息且 镜像正确,请尝试设置不同的名称服务器。
error: 'local-package.pkg.tar':权限被拒绝
如果您想使用 `pacman -U` 在 sshfs 挂载上安装软件包并收到此错误,请将软件包移动到本地目录并尝试再次安装。
error: 无法确定 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#下载基本工具中的注释,有关使用绑定挂载使 chroot 目录成为挂载点的解释和示例,请参阅 arch-chroot(8)。
error: GPGME 错误:无数据
如果您无法更新软件包并收到此错误,请在尝试更新之前尝试 `rm -r /var/lib/pacman/sync/`。
如果删除同步文件没有帮助,请在使用 `file /var/lib/pacman/sync/*` 检查同步文件是否为 `gzip compressed data`,然后再尝试更新。路由器或代理可能会损坏下载。
如果同步文件类型正确,则可能是镜像服务器有问题。使用 `pacman-conf -r core` 和 `pacman-conf -r extra` 查找正在使用的镜像服务器。将第一个返回的 URL 粘贴到浏览器中,并检查是否返回了文件列表。如果镜像返回错误,请在 `/etc/pacman.d/mirrorlist` 中注释掉它。
error: GPGME 错误:常规错误和 ":: File /var/cache/pacman/pkg/<package>.pkg.tar.zst is corrupted (invalid or corrupted package (PGP signature)).
如果发生此错误,并且例如您无法更新系统或任何软件包,则可能是您将 `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` 中)比 `/` 文件系统中已安装的软件包更新(例如,由于部分回滚),那么此方法是使根文件系统与本地数据库重新同步的适当方法。