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,因为这可能导致依赖问题。请参阅 System maintenance#Partial upgrades are unsupported 和 BBS#89328。安装特定软件包
要安装单个或一系列软件包(包括依赖项),请发出以下命令
# pacman -S package_name1 package_name2 ...
使用正则表达式安装一系列软件包(参见 此论坛帖子)
# pacman -S $(pacman -Ssq package_regex)
有时,不同的仓库(例如 extra 和 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
升级软件包
- 用户应遵循 System maintenance#Upgrading the system 部分的指导,定期升级其系统,而不是盲目运行以下命令。
- Arch 只支持完整的系统升级。有关详细信息,请参阅 System maintenance#Partial upgrades are unsupported 和 #Installing packages。
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/Tips and tricks。
对于高级功能,请安装 pkgfile,它使用包含所有文件及其关联软件包的单独数据库。
Pactree
查看软件包的依赖树
$ 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/ 目录,并且不会自动删除旧版本或未安装的版本。这有一些好处
- 它允许 降级软件包,而无需通过其他方式(如 Arch Linux Archive)获取前一个版本。
- 已卸载的软件包可以很容易地直接从缓存目录重新安装,而无需从仓库重新下载。
然而,有必要定期清理缓存,以防止目录无限增长。
paccache.script,包含在 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。这将改变被安装软件包以及被升级软件包的安装原因。软件包安装/升级/移除时发生什么
成功时,事务的工作流程包括五个高级步骤以及事务前/后的 hook
- 如果数据库没有被锁定,则初始化事务。
- 选择将在事务中添加或删除的软件包。
- 基于标志准备事务,对同步数据库、软件包及其依赖项执行健全性检查。
- 提交事务
- 如果适用,下载软件包(
_alpm_sync_load)。 - 如果存在 pacman
PreTransactionhook,则执行它们。 - 移除将被替换、冲突或明确目标为移除的软件包。
- 如果存在要添加的软件包,则提交每个软件包
- 如果软件包有安装脚本,则执行其
pre_install函数(或在升级或移除软件包的情况下为pre_upgrade或pre_remove)。 - pacman 删除软件包先前版本的(在升级或移除软件包的情况下)所有文件。但是,标记为软件包配置文件(参见 /Pacnew and Pacsave)的文件将被保留。
- pacman 解压软件包并将其文件转储到文件系统(在安装或升级软件包的情况下)。覆盖已保留的、手动修改的配置文件(参见上一步)的文件将被保存为新名称(.pacnew)。
- 如果软件包有安装脚本,则执行其
post_install函数(或在升级或移除软件包的情况下为post_upgrade或post_remove)。
- 如果软件包有安装脚本,则执行其
- 如果存在位于事务末尾的 pacman
PostTransactionhook,则执行它们。
- 如果适用,下载软件包(
- 释放事务和事务资源(即数据库锁)。
配置
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-sysusers 和 systemd-tmpfiles 结合使用,在安装软件包期间自动创建系统用户和文件。例如,tomcat8 指定它需要一个名为 tomcat8 的系统用户以及由该用户拥有的某些目录。pacman hook systemd-sysusers.hook 和 systemd-tmpfiles.hook 在 pacman 确定 tomcat8 包含指定用户和临时文件的文件时,调用 systemd-sysusers 和 systemd-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 命令。“提交事务失败(无效或损坏的软件包)”错误
在 /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
fuser /var/lib/pacman/db.lck 来验证是否仍有进程在使用它。安装时无法检索软件包
此错误表现为 Not found in sync db、Target not found 或 Failed retrieving file。
首先,请确保软件包确实存在。如果确定软件包存在,您的软件包列表可能已过时。尝试运行 pacman -Syu 来强制刷新所有软件包列表并进行升级。还要确保所选的 镜像是最新的,并且 仓库已正确配置。您还可以使用 Reflector 来保持镜像最新。
如果 pacman 报告没有可更新的内容,但仍继续显示 Failed retrieving file 错误,请考虑使用 pacman -Syyu 强制下载数据库。在正常情况下不需要这样做,所以请更仔细地检查 镜像的状态和一致性。
也可能是包含该软件包的仓库在您的系统上未启用,例如,软件包可能在 multilib 仓库中,但在您的 pacman.conf 中未启用 multilib。
另请参阅 FAQ#为什么官方仓库中每个共享库只有一个版本?。
修复因升级中断而无法引导的系统
无论是由于断电、内核恐慌还是硬件故障,升级都可能中断。在大多数情况下,损害不会太大,但系统很可能无法引导。
- 准备一个 USB 闪存安装介质并启动它。
- 挂载根文件系统以及您的 ESP。
- 使用
arch-chroot进入挂载的根文件系统。 - 检查
/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 因“数据库写入”错误在删除软件包时崩溃,并且之后重装或升级软件包失败,请执行以下操作:
- 使用 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/技巧和窍门#重新安装所有软件包。
- 升级后,一种检查未升级但仍损坏的软件包的方法是:
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 或升级整个系统。
在 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 依赖项。
- 从您选择的 镜像下载每个软件包。
- 将每个软件包解压到根目录。
- 使用
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 依赖项的此类过程示例。
重启后出现“无法找到根设备”错误
最可能是 initramfs 在 内核更新期间损坏(不当使用 pacman 的 --overwrite 选项可能是一个原因)。有两种选择;首先,尝试 Fallback 条目。
Tab 键,或(对于 GRUB 或 systemd-boot)按 e,将其重命名为 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。
“警告:当前区域设置无效;使用默认的“C”区域设置”错误
正如错误消息所示,您的区域设置未正确配置。参阅 Locale。
缺少区域设置警告消息
当区域设置文件被诸如 bleachbit 或 localepurgeAUR 等工具故意删除时,pacman 在软件包更新期间可能会发出关于缺少区域设置的警告。
要抑制这些警告,您可以注释掉 pacman.conf 中的 CheckSpace 选项。请记住,禁用 CheckSpace 会关闭所有软件包安装的空间检查功能,因此请仅在您有其他方法监控磁盘空间时使用此解决方法。
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 性能)解决了这些问题。在将 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 core 和 pacman-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,并且比 / 文件系统中的已安装软件包更新(例如,由于部分回滚),那么此方法是使根文件系统与本地数据库重新同步的合适方法。