pacman (简体中文) - ArchWiki

Jump to content

# pacman (简体中文)

From ArchWiki

翻译状态：本文是 pacman 的翻译。上次翻译日期：2021-09-16。如果英文版本有所更改，则您可以帮助同步翻译。

相关文章

- Creating packages (简体中文)
- 软件包降级
- pacman/Package signing (简体中文)
- pacman/Pacnew and Pacsave (简体中文)
- pacman/Rosetta (简体中文)
- pacman/Tips and tricks (简体中文)
- FAQ (简体中文)
- System maintenance (简体中文)
- Arch Build System (简体中文)
- Official repositories (简体中文)
- Arch User Repository (简体中文)

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

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

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

提示： pacman 软件包提供了如 makepkg 和 vercmp(8) 等工具。其它有用的工具如 pactree、checkupdates 等则在 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 包正则表达式)

有时软件包有多个版本，放在不同的仓库内（例如 extra 和 testing）。在以下示例中，要安装 extra 仓库的版本，需要在包名称前定义仓库名：

    # pacman -S extra/包名

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

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

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

    # pacman -S plasma-{workspace{,-wallpapers},pa}

##### 虚包

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

#### 安装包组

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

    # 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 不会删除软件自己创建的文件（例如主目录中的“点文件”不会被删除。）

### 升级软件包

警告：

- 建议用户遵守System maintenance (简体中文)#更新系统的指导，定期更新系统，并不盲目地执行这些命令。
- Arch 只支持系统完整升级，详细参见System maintenance (简体中文)#不支持部分升级和#安装软件包。

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

    # pacman -Syu

### 查询包数据库

pacman 使用 `-Q` 参数查询本地软件包数据库， `-S` 查询同步数据库，以及 `-F`查询文件数据库。要了解每个参数的子选项，分别参见 `pacman -Q --help`，`pacman -S --help`和`pacman -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 的一个处理后 hook用于在如果有处理产生孤立包后获得提示。这在当有软件包被仓库放弃时是有用的，因为任何被抛弃的包都会成为本地的一个孤立包（除非它是被显式安装的）。要避免在没有找到孤立包时"failed to execute command”的错误，在你的 hook 中为`Exec`使用如下的指令: `/usr/bin/bash -c "/usr/bin/pacman -Qtd || /usr/bin/echo '=> None found.'"`

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

    $ 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`来每周删除不使用的包。

提示： 可以使用 hook 自动执行清理，参考[1]和pacman-cleanup-hookAUR。

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

    # 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

要禁用 `-S`, `-U` 和 `-R` 动作，可以使用 `-p` 选项.

pacman 会列出需要安装和删除的软件，并在执行动作前要求需要的权限。

### 安装原因

pacman数据库按照软件包被安装的原因，将其分为两类：

- 显式安装：那些真正地被传递给通用pacman`-S`和`-U`命令的包；
- 依赖：那些虽然（一般）从未被传递给pacman安装命令，但由于被其它显式安装的包需要从而被隐式安装的包

当安装软件包时，可以把安装原因强制设为依赖:

    # pacman -S --asdeps package_name

该命令使用的原因通常是显式安装的包可能会提供可选安装包，这些包提供了非必须功能，可供用户自由选择。

提示： 用`--asdeps`安装可选依赖将确保如果你移除孤立包，pacman将会一同移除按照上述方法指定安装的可选依赖。

但是当重新安装该软件包时，安装原因将会被设为软件包所默认的。

显式安装的软件包列表可用`pacman -Qe`获取, 与之互补的已安装的依赖包可用`pacman -Qd`获取。

改变某个已安装软件包的安装原因，可以执行：

    # pacman -D --asdeps package_name

注意： 在升级时使用`--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

提示： 可以设置一个 `crontab` 或者 `systemd timer` 来定期同步文件信息数据库。

如果需要高级功能请安装 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.conf`。 man 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-sysusers`和`systemd-tmpfiles`结合来在安装包时自动创建系统用户和文件。例如，tomcat8指明它想要创建一个叫做`tomcat8`的系统用户和一些属于该用户的文件。当pacman确定tomcat8包含文件指明用户和临时文件时，pacman hooks `systemd-sysusers.hook`和`systemd-tmpfiles.hook`唤起`systemd-sysusers`和`systemd-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/Tips and tricks#Identify files not owned by any package。

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

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

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

参阅FAQ#Why is there only a single version of each shared library in the official repositories?.

### 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 更新时崩溃不起作用

即使 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盘），挂载你的根目录和启动分区，然后用 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`.

### Signature from "User <email@gmail.com>" is unknown trust, installation failed

试试以下途径：

- 更新已知密钥：`pacman-key --refresh-keys`;
- 手动升级`archlinux-keyring`软件包：`pacman -Sy archlinux-keyring && pacman -Su`.
- 查看pacman-key#Resetting all the keys.

### 请求导入 PGP keys

如果用过时的 ISO 安装 Arch，你很有可能被提示要导入 PGP keys。同意下载密钥来继续。如果你无法成功添加 PGP keys，更新或升级 keyring archlinux-keyring (浏览 above).

### Error: key "0123456789ABCDEF" could not be looked up remotely

如果软件包使用了新的密钥，且该密钥最近才被添加到 archlinux-keyring，那么这些密钥在更新过程中不可用于本地（先有鸡还是先有蛋的问题）。安装的 archlinux-keyring 不会包含这个密钥直到它被更新。Pacman 试图通过一个密钥服务器查询来绕过这个问题，这可能并不能完成（例如在代理或者防火墙后，导致上述错误）。先按照#Signature from "User <email@example.org>" is unknown trust, installation failed 所述更新 archlinux-keyring 在特别必要的情况下，尝试将密钥检测设置为Never。这可能会对系统造成灾难性的破坏。

### 不停看到错误 "PackageName: signature from "User <email@archlinux.org>" is invalid"

当系统时间错误时，签名密钥将会被认为过期（或无效）并且签名检查将会失败，提示以下错误信息：

    error: PackageName: signature from "User <email@archlinux.org>" is invalid
    error: failed to commit transaction (invalid or corrupted package (PGP signature))
    Errors occured, no packages were upgraded.

确保矫正系统时间，例如在安装或升级前从 root 执行 `ntpd -qg` ，和 `hwclock -w`。

### 'warning: current locale is invalid; using default "C" locale' 错误

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

### Pacman 不使用我的代理设置

正确设置环境变量（`$http_proxy`, `$ftp_proxy` 等）如果使用 sudo，需要让 sudo 将这些变量传递给 pacman.

### 如何重装所有包并保留安装和依赖信息？

重装所有软件包：`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 文件下载器得到了解决 (更多细节请参阅 Improve pacman performance ) 。当在 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 时，进入的目录不是挂载点。解决方法请参考 Install Arch Linux from existing Linux#Downloading basic tools， arch-chroot(8) 解释问题的原因，并提供了一个通过 bind mount 解决问题的方法。

### error: GPGME error: No data

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

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

## 另请参见

- Pacman 主页
- libalpm(3)
- pacman(8)
- pacman.conf(5)
- repo-add(8)

Categories:

- Package management (简体中文)
- Arch projects (简体中文)
- Commands (简体中文)