pacman

来自 Arch Linux 中文维基

Pacman软件包管理器是 Arch Linux 的一大亮点。它将一个简单的二进制包格式和易用的构建系统结合了起来。Pacman的目标是简化对软件包的管理,无论软件包是来自官方软件仓库还是用户自己创建的软件包。

Pacman 通过和主服务器同步软件包列表来保持系统是最新的。这种服务器/客户端模式可使得用户使用简单的命令,就能下载或安装软件包,并包含其所有必需的依赖包。

Pacman 用 C 语言编写,并使用 bsdtar(1) tar 作为打包格式。

提示:pacman 软件包提供了如 makepkgvercmp(8) 等工具。其它有用的工具如 pactreecheckupdates 等则在 pacman-contrib 软件包中(它曾是 pacman 的一部分)。运行 pacman -Ql pacman | grep -E 'bin/.+' 可查看完整的工具列表。

用法[编辑 | 编辑源代码]

以下只是 pacman 可以执行的操作的一小部分示例。要阅览更多示例可参考 pacman(8)

提示: 对于以前使用过其他 Linux 发行版的用户,Pacman Rosetta 这篇对比文章将大有帮助。

安装软件包[编辑 | 编辑源代码]

一个软件包就是一个归档包,其中包含:

  • 该软件所有(编译好的)文件,并按照每个文件的安装位置储存在一个与根目录结构相同的目录中
  • 该软件的元数据,例如软件名称、版本和依赖等
  • 供 pacman 使用的其它描述性文件
  • (可选)在安装、升级、卸载时执行的安装脚本

Arch 的软件包管理器 pacman 可以安装、更新和删除这些软件包。使用软件包而不是自己编译和安装程序有很多好处:

  • 轻松升级:pacman 会在更新可用时立即更新已安装的软件包
  • 依赖检查:pacman 会为你处理依赖问题,只需要指明程序(名),pacman 就会将它和它所需的所有其他程序都一起安装。
  • 干净卸载:pacman 持有软件包包含的所有文件的列表。这样一来,当你决定移除软件包时,不会无意留下任何文件。
注意:
  • 软件包通常有可选依赖,它们为软件提供额外的功能,但并不是软件运行所必需的。安装软件时, pacman 会列出软件包的可选依赖, 但这份列表不会记载在 pacman.log 中。请使用#查询包数据库命令查询软件包的可选依赖。
  • 当你安装软件包以作为一些其他的软件包的(可选)依赖时(即没有明确要求安装时),推荐使用 --asdeps 选项。请参阅#安装原因一节了解详细内容。
警告: 在 Arch 上安装软件包时,请避免在还没有更新系统前刷新同步软件包列表(例如,当官方软件仓库不再提供某个软件包时)。实际操作上,请使用 pacman -Syu 软件包名, 而不要使用 pacman -Sy 软件包名,因为后者可能会导致依赖问题。参见 System maintenance#不支持部分升级一文和 BBS#89328 论坛讨论

安装指定的包[编辑 | 编辑源代码]

要安装单个或者一系列软件包(包含软件包的依赖),请使用如下命令:

# pacman -S 包名_1 包名_2 ...

要通过正则表达式安装一系列软件包(参见 这个论坛帖子):

# pacman -S $(pacman -Ssq 包正则表达式)

有时软件包有多个版本,放在不同的仓库内(例如 extratesting)。在以下示例中,要安装 extra 仓库的版本,需要在包名称前定义仓库名:

# pacman -S extra/包名

要安装多个含有相似名称的软件包,可以使用花括号扩展。例如:

# pacman -S plasma-{desktop,mediacenter,nm}

可以多层扩展到需要的层次:

# pacman -S plasma-{workspace{,-wallpapers},pa}
虚包[编辑 | 编辑源代码]

虚拟软件包是一个特殊的软件包,它本身并不存在,但由一或多个其它软件包提供。虚拟软件包允许其它软件包不以某一个特定的包为依赖,以应对有多个候选的情况。虚包不能用它们的名称安装,相反它们会在你安装提供虚包的软件包时被安装到你的系统中。

提示:当存在多个候选的情况下,可选包列表先按照pacman.conf中仓库出现的顺序排序,同一个仓库有多个可选再按字母顺序排序。

安装包组[编辑 | 编辑源代码]

一些包属于一个可以同时安装的软件包组。例如,运行下面的命令

$ pacman -S gnome

会提醒用户选择 gnome 内需要安装的包。

有的包组包含大量的软件包,有时用户只需其中几个。除了逐一键入序号外,pacman 还支持选择或排除某个区间内的的软件包:

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/groups/ 查看可用的包组。

注意: 如果列表中的包已经安装在系统中,它会被重新安装,即使它已经是最新的。可以用 --needed 选项覆盖这种行为。

删除软件包[编辑 | 编辑源代码]

删除单个软件包,保留其全部已经安装的依赖关系

# pacman -R package_name

删除指定软件包,及其所有没有被其他已安装软件包使用的依赖关系:

# pacman -Rs package_name
警告: 删除类似 gnome 这样的软件包组时,将会忽略组中软件包的安装原因,因为实际操作上执行的是逐一删除软件组的每一个软件,依赖软件包的安装原因不会被忽略。

上面这条命令在移除包含其他所需包的组时有时候会拒绝运行。这种情况下可以尝试

# pacman -Rsu package_name

要删除软件包和所有依赖这个软件包的程序:

警告: 此操作是递归的,请小心检查,可能会一次删除大量的软件包。
# pacman -Rsc package_name

要删除一个被其他软件包依赖的软件包,但是不删除依赖这个软件包的其他软件包:

警告: 此操作有破坏系统的能力,应该尽量避免使用。详情请看 避免某些 Pacman 命令
# pacman -Rdd package_name

pacman 删除某些程序时会备份重要配置文件,在其后面加上*.pacsave扩展名。-n 选项可以避免备份这些文件:

pacman -Rn package_name
注意: pacman 不会删除软件自己创建的文件(例如主目录中的“点文件”不会被删除。)

升级软件包[编辑 | 编辑源代码]

警告:

一个 pacman 命令就可以升级整个系统。花费的时间取决于系统有多老。这个命令会同步非本地(local)软件仓库并升级系统的软件包:

# pacman -Syu

查询包数据库[编辑 | 编辑源代码]

pacman 使用 -Q 参数查询本地软件包数据库, -S 查询同步数据库,以及 -F查询文件数据库。要了解每个参数的子选项,分别参见 pacman -Q --helppacman -S --helppacman -F --help

pacman 可以在包数据库中查询软件包,查询位置包含了软件包的名字和描述:

$ pacman -Ss string1 string2 ...

有时,-s的内置正则会匹配很多不需要的结果,所以应当指定仅搜索包名,而非描述或其他子段:

$ 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

要罗列所有不再作为依赖的软件包(孤立orphans):

$ pacman -Qdt

要罗列所有明确安装而且不被其它包依赖的软件包:

$ pacman -Qet

更多例子查看pacman tips

Pactree[编辑 | 编辑源代码]

注意: pactree(8)不再是pacman的一部分。它现在在pacman-contrib中。

要显示软件包的依赖树:

$ pactree package_name

检查一个安装的软件包被那些包依赖,将递归标识-r传递给 pactree,或者使用 pkgtoolsAUR中的whoneeds

数据库结构[编辑 | 编辑源代码]

pacman数据库通常位于 /var/lib/pacman/sync. 对于每一个在/etc/pacman.conf中指定的软件仓库, 这里都有一个一致的数据库。数据库文件夹里每个tar.gz文件都包含着一个仓库的软件包信息。例如which 包:

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

这个 depends 项列出了该软件的依赖包, 而desc有该包的介绍,例如文件大小和MD5值 。

清理软件包缓存[编辑 | 编辑源代码]

pacman 将下载的软件包保存在 /var/cache/pacman/pkg/ 并且不会自动移除旧的和未安装版本的软件包。这样做有一些好处:

  1. 这样允许降级软件包而不需要通过其他方式提取旧版本,例如 Arch Linux Archive.
  2. 被卸载的软件包可以轻易地直接从缓存文件夹重新安装,不需要重新从软件仓库下载。

然而,需要定期手动清理缓存来避免该文件夹无限制增大。

pacman-contrib 提供的 paccache(8) 脚本默认会删除所有缓存的版本和已卸载的软件包,除了最近的3个会被保留:

# paccache -r

启用启动 paccache.timer来每周删除不使用的包。

提示:可以使用#钩子自动执行清理,安装 pacman-cleanup-hookAUR 参考[1]

也可以自己设置保留最近几个版本:

# paccache -rk1

添加-u/--uninstalled开关来限制paccache的行为只作用于卸载的包。例如清理所有卸载的包的缓存版本,可以用以下命令:

# paccache -ruk0

更多参数参见paccache -h

pacman也有一些内建参数用于清除缓存和那些不再在/etc/pacman.conf配置文件中列出的软件仓库残留数据库文件。然而pacman并不提供保留一定数量的过去版本的功能,因此它比paccache的默认选项更加激进。

要删除目前没有安装的所有缓存的包,和没有被使用的同步数据库,执行:

# pacman -Sc

要删除缓存中的全部文件,使用两次-c开关。这是最为激进的方式,将会清空缓存文件夹:

# pacman -Scc
警告: 应当避免从缓存中删除所有过去版本和卸载的包,除非需要更多磁盘空间。这样会导致无法降级或重新安装包而不再次下载他们

pkgcachecleanAUR以及pacleanerAUR是两个进一步清理缓存的替代工具

其它命令[编辑 | 编辑源代码]

升级系统时安装其他软件包:

# pacman -Syu package_name1 package_name2 ...

下载包而不安装它:

# pacman -Sw package_name

安装一个本地包(不从源里下载):

# pacman -U /path/to/package/package_name-version.pkg.tar.zst

要将本地包保存至缓存,可执行:

# 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,的动作并列出涉及该动作相关软件的列表,可以使用--print或缩写-p

可以添加--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,是不被推荐的。这会导致不仅改变要被安装的软件包的安装原因,也会改变被升级的软件包的安装原因。

查询一个包含具体文件的包名[编辑 | 编辑源代码]

同步文件数据库:

# pacman -Fy

查询包含某个文件的包名,比如:

# pacman -F pacman
core/pacman 5.0.1-4
    usr/bin/pacman
    usr/share/bash-completion/completions/pacman
extra/xscreensaver 5.36-1
    usr/lib/xscreensaver/pacman
提示: 可以启用/启动 pacman-filesdb-refresh.timer(该定时器在pacman-contrib中)来每周同步文件信息数据库。

如果需要高级功能请安装 pkgfile,它使用一个单独的数据库来保存文件和它们所关联的软件包的信息。

安装/更新/删除 软件包时发生了什么[编辑 | 编辑源代码]

动作成功执行时,事务包含五大步骤和事务钩子程序:

  1. 如果数据库未被锁定,初始化事务
  2. 确认事务中要添加或删除的软件包
  3. 准备事务,根据参数,对同步数据库、软件包和依赖关系进行校验
  4. 提交事务:
    1. 如果需要,下载软件包 (_alpm_sync_load)
    2. 如果有可以执行的 pacman PreTransaction 钩子,执行这些钩子.
    3. 被替换、出现冲突或被指定删除的软件包将会被删除
    4. 如果需要添加软件包,每个软件包都会执行提交
      1. 如果有安装脚本,执行 pre_install 函数(更新时执行 pre_upgrade,删除时执行 pre_remove).
      2. pacman 删除软件包之前版本的所有文件 (在更新或删除软件包时)。配置文件将会被保留 (请参阅 Pacman/Pacnew and Pacsave).
      3. pacman 将软件包文件解压到系统(安装或升级软件包时). 会覆盖旧的已被手动修改的配置文件时,配置文件会命名为 (.pacnew).
      4. 如果软件包有安装脚本,执行 post_install 函数(更新时执行 post_upgrade,删除时执行 post_remove).
    5. 如果pacman PostTransaction 钩子可执行,执行这些钩子.
  5. 释放事务及事务资源 (例如,数据库锁)

配置[编辑 | 编辑源代码]

pacman 的配置文件位于/etc/pacman.confman pacman.conf 可以查看配置文件的进一步信息。

通用选项[编辑 | 编辑源代码]

通用选项都在[options]段。阅读 man 手册或者查看默认的 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

启用并行下载[编辑 | 编辑源代码]

Pacman 6.0 增加了并行下载选项,将 /etc/pacman.conf[options] 选项 ParallelDownloads 设置成正整数,例如 5,将会同时下载 5 个软件包,如果未设置此选项,软件包将会被依次下载。

在升级时跳过软件包[编辑 | 编辑源代码]

警告: 在跳过软件包时要小心,因为部分升级不受支持

要想在升级系统时跳过特定的软件包,用像如下的命令指明:

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会在更新locales已经被localepurge或者bleachbit清除的包时发出警告。将CheckSpace参数加入pacman.conf能够抑制这种警告,但是要意识到space-check功能将会对所有软件包禁用。

保留多个配置文件[编辑 | 编辑源代码]

如果你有多个配置文件(比如,主配置和启用了测试仓库的配置文件),需要共享一些设置,你可以在配置文件中使用Include选项,例如:

Include = /path/to/common/settings

/path/to/common/settings文件中是两个配置文件共享的相同配置。

钩子[编辑 | 编辑源代码]

pacman可以在处理前后,运行/usr/share/libalpm/hooks/文件夹下的hooks,更多的hooks文件夹可以通过HooDir选项在pacman.conf中指明,默认/etc/pacman.d/hooks。Hook文件必须以.hook为后缀。Pacman hooks不是交互式的。

pacman hooks用于,比如说,和systemd-sysuserssystemd-tmpfiles结合来在安装包时自动创建系统用户和文件。例如,tomcat8指明它想要创建一个叫做tomcat8的系统用户和一些属于该用户的文件。当pacman确定tomcat8包含文件指明用户和临时文件时,pacman hooks systemd-sysusers.hooksystemd-tmpfiles.hook唤起systemd-sysuserssystemd-tmpfiles

有关 alpm hooks 的更多信息,参见alpm-hooks(5)

软件仓库[编辑 | 编辑源代码]

除了特殊的通用选项节, 每个pacman.conf中的[section]都定义了一个使用的软件包仓库,仓库是多个软件包的逻辑上的集合,他们物理上存储在一个或多个服务器:这也是为什么每一个服务器都叫做这个仓库的镜像

仓库区分为官方仓库非官方仓库。配置文件中仓库的顺序十分重要;当几个仓库出现同名安装包,不管版本号如何,pacman将使用配置文件中排前的仓库。要在添加后使用某个仓库,你需要先升级整个系统

每个仓库节都可以直接指定镜像列表或者Include引用其他的文件:例如,官方镜像引用了/etc/pacman.d/mirrorlist/。具体查看Mirrors

软件包的缓存目录[编辑 | 编辑源代码]

pacman.conf通用选项节,CacheDir指定了Pacman下载的安装包缓存位置(如果未设置,默认位置为 /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

疑难解答[编辑 | 编辑源代码]

"Failed to commit transaction (conflicting files)" 错误[编辑 | 编辑源代码]

如果碰到如下错误:[2]

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 不会覆盖文件。这是设计功能,不是缺陷。

这个问题通常很容易解决(当然你首先应该尝试搞清楚这些文件是怎么变成这样的)。一个安全的方式是,首先检查是否有另一个软件包提供了这个文件 (pacman -Qo /path/to/file)。如果文件被另一个软件包所有,请报告问题。如果不是其它软件包提供,将 'exists in filesystem' 的文件重命名并重新运行update命令。如果一切顺利,可以删掉这个文件。

如果你手动安装了一个软件,没有通过pacman,例如用make install,你必须将软件连同它的全部文件一起移除/卸载。参见Pacman/提示和技巧#查找不属于任何软件包的文件

每一个安装的软件包都会提供一个 /var/lib/pacman/local/$package-$version/files 文件,包含此软件包的元数据。如果文件损坏或者丢失,将会导致升级时出现file exists in filesystem 错误。此错误通常只会影响一个软件包,除了手动删除或移动所有的问题文件,你也可以显式地使用pacman -S --overwrite glob packagepacman 强制覆盖匹配glob的文件。

警告: 尽量避免使用--overwrite开关。参见System maintenance#避免某些 pacman 命令

"Failed to commit transaction (invalid or corrupted package)" 错误[编辑 | 编辑源代码]

看看/var/cache/pacman/pkg中是否有*.part结尾的文件,它们是没有完全下载的文件,删除它们并重新执行更新。这些程序一般是自定义的XferCommand 下载命令造成的。

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

同样的错误也可能是因为archlinux-keyring过期所致,阻止了pacman验证签名。详情见Pacman/Package signing#Upgrade system regularly以修复并避免在未来遇到同样问题。

"Failed to init transaction (unable to lock database)" 错误[编辑 | 编辑源代码]

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 db, Target not foundFailed retrieving file.

首先确认软件包确实存在(并注意错别字)。如果确认软件包存在,可能本地数据库过时了或者软件仓库没有配置好,试试 pacman -Syyu 强制数据库更新和升级。

也有可能包含该软件包的软件仓库没有启动。例如,该软件包可能在 multilib 仓库里,但该仓库没有在 pacman.conf 中启用。

参阅常见问题#Q) 在官方仓库中,为什么只为每个共享链接库提供一个版本?.

pacman 更新时崩溃[编辑 | 编辑源代码]

如果 pacman 在删除、重新安装或更新软件包时 "数据库写入" 出错:

  1. 从 Arch 安装媒体启动,最好用最新的安装媒体
  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 --sysroot /mnt -Syu来更新系统的 pacman 数据库。
  5. 如果无法更新,可以 重新安装所有软件包
  6. 更新之后,可以通过下面命令确认是否还存在损坏的包:find /mnt/usr/lib -size 0
  7. 通过pacman --sysroot /mnt -S package重新安装依然损坏的软件包

pacman: command not found[编辑 | 编辑源代码]

如果/var/cache/pacman/pkg是一个符号链接,pacman在升级自身时会创建该目录并移除符号链接,这会导致升级失败,并产生/usr/bin/pacman 与其它 pacman包中内容丢失的后果。

永远不要为/var/cache/pacman/pkg创建软连接,因为该目录受pacman控制。使用CacheDir选项或通过绑定挂载。参见#软件包的缓存目录

如果你已经遇到这个问题,你可以手动提取安装包中/usr的内容恢复,并重新安装pacman。详情见FS#73306论坛相关话题

手动重新安装 pacman[编辑 | 编辑源代码]

使用 pacman-static[编辑 | 编辑源代码]

pacman-staticAURpacman的静态编译版本,因此系统中的库文件失效时依然可以运行它。当部分升级pacman无法运行,静态编译版本就能够派上用场。

置顶评论和PKGBUILD提供了直接下载二进制文件的方法,可以用于重新安装pacman或在部分升级情况下升级整个系统。

使用外部 pacman[编辑 | 编辑源代码]

如果pacman-static也无法使用,考虑使用外部pacman。 最简单的办法是使用archiso并指定--sysroot--root参数到挂载点。参见Chroot#使用 arch-chroot来挂载--sysroot参数需要的文件系统。

手动提取[编辑 | 编辑源代码]

警告: 这种方式极其容易破坏你的系统,把它变得更糟。这个方式只是作为最后的措施,以防万一#pacman 更新时崩溃不起作用

即使 pacman 严重损坏,你仍可以手动修复它,这需要下载最新的包并把它们解压到正确的目录。大致步骤如下:

  1. 确定要安装的pacman依赖项
  2. 从你选择的mirror下载每个包
  3. 把每个包解压到 root
  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依赖项损坏。

升级系统重启后,出现"unable to find root device"错误,无法登录[编辑 | 编辑源代码]

很有可能 initramfs内核升级时损坏(例如由错误地使用 pacman--overwrite 选项导致)。有两个选择;首先尝试 Fallback启动项。

提示:万一你删除了 Fallback 启动项,你总可以在启动加载器菜单显示出来的时候按Tab键(对于 Syslinux)或者按e键(对于 GRUB 或者 systemd-boot),将它重命名为initramfs-linux-fallback.img然后按Enter或者b(取决于你的启动加载器以新参数启动的方式)

一旦系统启动,从控制台或终端(为备用linux内核)运行这条命令来重建 initramfs 映像:

# mkinitcpio -p linux

如果上面方法不行,从一个最新的 Arch 发行版本(CD/DVD 或者 U盘),分别挂载你的根目录和启动分区到/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 镜像,不需要单独生成。

之后建议执行 exit, umount /mnt/{boot,} 然后 reboot.

'warning: current locale is invalid; using default "C" locale' 错误[编辑 | 编辑源代码]

错误信息已经很明确了,locale 设置不正确,请阅读Locale进行设置。

Pacman 不使用我的代理设置[编辑 | 编辑源代码]

正确设置环境变量($http_proxy, $ftp_proxy 等)。如果使用 sudo,需要让 sudo 将这些变量传递给 pacman。另外,在更新密钥前确保/etc/pacman.d/gnupg/dirmngr.conf路径的 dirmngr配置文件honor-http-proxy变量设置正确。

如何重装所有包并保留安装和依赖信息?[编辑 | 编辑源代码]

重装所有软件包:pacman -S $(pacman -Qnq)-S 选项会保留安装缘由)。

接着需要重装外来包(不在官方仓库里的软件包)。外来包可通过pacman -Qmq查看。

"Cannot open shared object file" 错误[编辑 | 编辑源代码]

有可能是前一次 pacman 事务中删除或者损坏了 pacman 自身需要的一些共享库。

要修复这种情况,你需要手动解压那些共享库文件到文件系统中合适的地方。首先请查明哪个包中包含有所需的库文件,然后在 pacman 缓存中 (/var/cache/pacman/pkg/) 找到对应的包。解压出需要的库文件到文件系统的对应位置,如此可以继续使用 pacman

之后需要重新安装损坏的软件包。注意你可能需要使用 --overwrite 选项覆盖掉你刚刚解压出的系统文件,因为 pacman 可能没有跟踪到对应的文件信息。 pacman 随后会使用包中的文件正确替换掉共享库文件。如此能修好您的 pacman ,然后请继续更新系统中剩下的软件包。

软件包下载停滞[编辑 | 编辑源代码]

一些网络问题可能会报告阻止了 pacman 更新和同步仓库。[3] [4] 在实体机中安装 Arch Linux 时,这些问题已经通过替换默认的 pacman 文件下载器得到了解决 (更多细节请参阅 Pacman/提示和技巧#性能 ) 。当在 VirtualBox 中安装 Arch Linux 作为客户操作系统时,这个问题也通过在主机属性中使用主机界面而不是 NAT 来解决。

无法从镜像服务器获取 'core.db'[编辑 | 编辑源代码]

如果从正确的镜像服务器收到此错误,请换一个域名解析服务器

error: 'local-package.pkg.tar': permission denied[编辑 | 编辑源代码]

如果你想要在一个 sshfs 上使用pacman -U安装软件包并遇到了这个错误,将包移动到本地目录,再试一次。

error: could not determine cachedir mount point /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 时,进入的目录不是挂载点。解决方法请参考 从现有 Linux 发行版安装 Arch Linux#下载基本工具arch-chroot(8) 解释问题的原因,并提供了一个通过 bind mount 解决问题的方法。

error: GPGME error: No data[编辑 | 编辑源代码]

如果你无法更新包,并遇到了该问题,尝试

rm -r /var/lib/pacman/sync/

后再次更新。

如果删除sync中的同步文件不能解决问题,请通过file /var/lib/pacman/sync/*检查同步文件是否为gzip compressed data,使用路由或代理可能会损坏下载的文件。

如果同步文件是正确的类型,那么问题可能出在镜像源上。使用pacman-conf -r corepacman-conf -r extra查询使用的镜像源,将命令输出的第一个URL粘贴到浏览器访问,检查返回的文件。如果返回有问题,在{ic|/etc/pacman.d/mirrorlist}}里修改为其他可用镜像源。

另请参见[编辑 | 编辑源代码]