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
。这将更改不仅要安装的软件包的安装理由,还会更改要升级的软件包的安装理由。软件包安装/升级/移除期间发生了什么
成功时,事务的工作流程遵循五个高级步骤,外加 pre/post 事务钩子
- 如果数据库未锁定,则初始化事务。
- 选择将在事务中添加或移除哪些软件包。
- 通过对同步数据库、软件包及其依赖项执行健全性检查,根据标志准备事务。
- 提交事务
- 如果适用,下载软件包 (
_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 包含指定用户和临时文件的文件时,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/
中绑定挂载选定的目录。
/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:未找到命令
如果 /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
来指定要对其执行操作的系统的挂载点。有关如何挂载 --sysroot
所需的必要文件系统,请参阅 Chroot#使用 chroot。
通过手动提取
即使 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
键或 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
。
“警告:当前语言环境无效;使用默认的 "C" 语言环境” 错误
正如错误消息所说,您的语言环境配置不正确。请参阅 语言环境。
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”失败
如果您收到此错误消息,并且 镜像 正确,请尝试设置不同的 名称服务器。
错误:“local-package.pkg.tar”:权限被拒绝
如果您想使用 pacman -U
在 sshfs 挂载点上安装软件包并收到此错误,请将软件包移动到本地目录并再次尝试安装。
错误:无法确定 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)。
错误: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
中注释掉它。
错误:GPGME 错误:一般错误和“:: 文件 /var/cache/pacman/pkg/<软件包>.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
中)比 /
文件系统中的已安装软件包更新(例如,由于部分回滚),那么此方法是使根文件系统与本地数据库重新同步的适当方法。