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 Archive)检索以前的版本。
- 已卸载的软件包可以轻松地直接从缓存目录重新安装,而无需从仓库重新下载。
但是,有必要定期故意清理缓存,以防止目录大小无限增长。
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
文件包含两种配置的相同选项。
钩子 (Hooks)
Pacman 可以从 /usr/share/libalpm/hooks/
目录运行事务前和事务后钩子;可以使用 pacman.conf
中的 HookDir
选项指定更多目录,默认为 /etc/pacman.d/hooks
。钩子文件名必须以 .hook 为后缀。Pacman 钩子是非交互式的。
Pacman 钩子用于例如结合 systemd-sysusers
和 systemd-tmpfiles
,在软件包安装期间自动创建系统用户和文件。例如,tomcat8 指定它需要一个名为 tomcat8
的系统用户以及此用户拥有的某些目录。当 pacman 确定 tomcat8 包含指定用户和临时文件的文件时,pacman 钩子 systemd-sysusers.hook
和 systemd-tmpfiles.hook
会调用 systemd-sysusers
和 systemd-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
fuser /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
需要复制确切的升级以确保正确的脚本和小工具和钩子将运行。
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
- 如果系统使用默认数据库和目录位置,您现在可以更新系统的 pacman 数据库并通过
pacman --root=/mnt --cachedir=/mnt/var/cache/pacman/pkg -Syu
以 root 身份升级它。- 或者,如果您无法更新/升级,请参考 Pacman/技巧和窍门#重新安装所有软件包。
- 升级后,一种双重检查未升级但仍然损坏的软件包的方法:
find /mnt/usr/lib -size 0
- 然后通过
pacman --root /mnt --cachedir=/mnt/var/cache/pacman/pkg -S package
重新安装任何仍然损坏的软件包。
pacman: command not found (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 依赖项
- 从您选择的 镜像 下载每个软件包
- 将每个软件包提取到根目录
- 使用
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 在 内核 更新期间损坏(不当使用 pacman 的 --overwrite
选项可能是原因之一)。有两种选择;首先,尝试 Fallback 条目。
Tab
键(对于 Syslinux)或 e
键(对于 GRUB 或 systemd-boot),将其重命名为 initramfs-linux-fallback.img
并按 Enter
或 b
键(取决于您的 启动加载程序)以使用新参数启动。系统启动后,从控制台或终端运行此命令(对于标准的 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 (警告:当前区域设置无效;使用默认 "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 也解决了此问题。
Failed retrieving file 'core.db' from mirror (无法从镜像检索文件 'core.db')
如果您收到此错误消息,并且 镜像 正确,请尝试设置不同的 名称服务器。
error: 'local-package.pkg.tar': permission denied (错误:'local-package.pkg.tar':权限被拒绝)
如果您想使用 pacman -U
在 sshfs 挂载上安装软件包并收到此错误,请将软件包移动到本地目录并再次尝试安装。
error: could not determine cachedir mount point /var/cache/pacman/pkg (错误:无法确定 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 (错误: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 error: General error and ":: File /var/cache/pacman/pkg/<package>.pkg.tar.zst is corrupted (invalid or corrupted package (PGP signature)). (错误: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
,与 /
文件系统中的已安装软件包相比,它是最新的(例如,由于部分回滚),那么此方法是使根文件系统与本地数据库重新同步的适当方法。