pacman/提示和技巧 - Arch Linux 中文维基

跳转到内容

# pacman/提示和技巧

来自 Arch Linux 中文维基
< Pacman

翻译状态：

- 本文（或部分内容）译自 Pacman/Tips and tricks，最近一次同步于 2025-01-23，若英文版本有所更改，则您可以帮助同步与翻译更改的内容。
- 您可以在 ArchWiki 的对应页面找到本文翻译的原始修订历史。
- 本文可能与英文原文存在出入。

相关文章

- 镜像源
- 创建软件包

通用优化请参考核心工具和 Bash。

## 维护

注意：您也可以使用 `grep -Fxf` 或 `grep -Fxvf`，而不是像下面的章节中一样使用 comm（需要排序输入和 sort）。

另见系统维护。

### 查询软件包

#### 未使用的软件库

默认情况下，`pacman.conf` 中列出的软件库用于同步、搜索、安装和升级。可以通过更改配置来增加灵活性，例如仅使用某些软件库进行搜索[1]：

    /etc/pacman.conf

    ...
    [multilib]
    Usage = Sync Search
    ...

参见 pacman.conf(5) § REPOSITORY SECTIONS。

#### 带有版本

您可能希望获得已安装的软件包及其版本的列表，这在报告错误或讨论已安装的软件包时非常有用。

- 所有明确安装的软件包：`pacman -Qe`。
- 列出 `group` 软件包组中的所有软件包：`pacman -Sg group`。
- 所有外部软件包 (通常是手动下载安装，或者已经从数据库中删除)：`pacman -Qm`。
- 列出所有从数据库中安装的软件包：`pacman -Qn`。
- 所有明确安装的，存在于数据库而且不是直接或可选依赖的软件包：`pacman -Qent`。
- 按正则表达式查询软件包：`pacman -Qs regex`。
- 按正则表达式查询软件包，自定义输出格式（需要 expac包）：`expac -s "%-30n %v" regex`。
- 从数据库查询软件包，（如如需iwd包）: `pacman -Ss iwd`

#### 带有大小

在尝试释放硬盘上的空间时，弄清楚哪些软件包最大可能非常有用。这里有两个选项：获取单个包的大小，或者获取包的大小及其依赖关系。

##### 单个包

用下面命令查看单个软件包的大小:

    $ LC_ALL=C.UTF-8 pacman -Qi | awk '/^Name/{name=$3} /^Installed Size/{print $4$5, name}' | LC_ALL=C.UTF-8 sort -h

##### 软件包和依赖项

要列出软件包及其依赖项，

- 安装 expac包 并运行 `expac -H M '%m\t%n' | sort -h`。
- 运行 pacgraphAUR 带 `-c` 选项。

查询软件包的下载大小（不加 `packages` 将查询所有软件包）：

    $ expac -S -H M '%k\t%n' packages

要列出不属于元软件包 base包 或软件包组 xorg包组 中的明确安装的包，带大小和描述：

    $ expac -H M "%011m\t%-20n\t%10d" $(comm -23 <(pacman -Qqen | sort) <({ pacman -Qqg xorg; expac -l '\n' '%E' base; } | sort -u)) | sort -n

要列出标记为可升级的软件包及其下载大小：

    $ expac -S -H M '%k\t%n' $(pacman -Qqu) | sort -sh

要仅列出可选依赖：

    $ expac -S "%o" package

#### 按日期查询

用 expac包 查询最近安装的 20 个软件包：

    $ expac --timefmt='%Y-%m-%d %T' '%l\t%n' | sort | tail -n 20

或者，用从 epoch(1970-01-01 UTC) 开始的秒数：

    $ expac --timefmt=%s '%l\t%n' | sort -n | tail -n 20

#### 不在指定的包组、软件库或元包中

注意：要获取作为依赖项安装但已没有任何包依赖它的包的列表，见#删除未使用的软件包（孤立软件包）.

列出不在 base包 元软件包中的明确安装的软件包：

    $ comm -23 <(pacman -Qqe | sort) <(expac -l '\n' '%E' base | sort)

列出不在 base包 元软件包或 xorg包组 软件包组中的明确安装的软件包：

    $ comm -23 <(pacman -Qqe | sort) <({ pacman -Qqg xorg; expac -l '\n' '%E' base; } | sort -u)

列出所有没有任何软件包依赖它的已安装软件包，并且这些软件包不在 base包 元软件包或 xorg包组 软件包组中：

    $ comm -23 <(pacman -Qqt | sort) <({ pacman -Qqg xorg; echo base; } | sort -u)

同上，但带描述：

    $ expac -H M '%-20n\t%10d' $(comm -23 <(pacman -Qqt | sort) <({ pacman -Qqg xorg; echo base; } | sort -u))

列出不在指定软件库 repo_name 中的所有已安装软件包（可以同时检查多个软件库）：

    $ comm -23 <(pacman -Qq | sort) <(pacman -Sql repo_name | sort)

列出在指定软件库 repo_name 中的所有已安装软件包（可以同时检查多个软件库）：

    $ comm -12 <(pacman -Qq | sort) <(pacman -Sql repo_name | sort)

列出 Arch Linux ISO 上不在 base包 元软件包中的所有包：

    $ comm -23 <(curl https://gitlab.archlinux.org/archlinux/archiso/-/raw/master/configs/releng/packages.x86_64) <(expac -l '\n' '%E' base | sort)

提示：或者，使用 moreutils包 包中的 `combine`（而不是 `comm`），该命令的语法更容易记住。见 combine(1)。

#### 开发版软件包

要列出所有开发版/不稳定软件包，请运行：

    $ pacman -Qq | grep -Ee '-(bzr|cvs|darcs|git|hg|svn)$'

#### 软件包的依赖项

要获得包的依赖项列表，最简单的解决方案是读取以下命令的输出：

    $ pacman -Qi package

要实现自动化，而不是分析 pacman 输出这种容易出错的方法，使用 expac包：

    $ expac -S '%D' package

#### 带有可选依赖

要列出明确安装的软件包及其可选依赖，请运行：

    $ LC_ALL=C.UTF-8 pacman -Qei | sed '/^[^NO ]/d;/None$/d' | awk 'BEGIN{RS=ORS="\n\n";FS=OFS="\n\\S"} /Optional Deps/ {print $1"\nO"$2}'

或者，使用 expac包：

    $ expac -d '\n\n' -l '\n\t' -Q '%n\n\t%O' $(pacman -Qeq)

要列出它们并忽略已安装的可选依赖，请运行：

    $ LC_ALL=C.UTF-8 pacman -Qei | sed '/^[^NO ]/d;/None$/d' | awk 'BEGIN{RS=ORS="\n\n";FS=OFS="\n\\S"} /Optional Deps/ {print $1"\nO"$2}' | sed 's/^Optional Deps   ://;/\[installed\]$/d;s/\s\+/ /'

#### 查看特定打包者打包的所有软件包

这里用到了 gawk包。

    $ pacman -Qi | awk -F': ' '/^名字/ {name=$2} /^打包者/ && $2 ~ /特定打包者/ {print name}'

### 浏览软件包

要浏览所有已安装软件包并即时预览每个软件包：

    $ pacman -Qq | fzf --preview 'pacman -Qil {}' --layout=reverse --bind 'enter:execute(pacman -Qil {} | less)'

这使用 fzf（英语：fzf） 来显示一个两窗格视图，其中列出了所有软件包，包信息显示在右侧。

输入字母以过滤包列表；使用箭头键（或 `Ctrl-j`/`Ctrl-k`）浏览；按 `Enter` 在 less 下查看包信息。

要使用 fzf 以类似的方式浏览当前已知的所有 pacman 软件包（已安装和尚未安装），请使用：

    $ pacman -Slq | fzf --preview 'pacman -Si {}' --layout=reverse

浏览的按键绑定是相同的，不过 `Enter` 不能同样工作。

### 列出软件包拥有的文件并带大小

如果您发现某个特定的包使用了大量空间，并且您想知道哪些文件占了其中的大部分，那么这个命令可能会很有用。

    $ pacman -Qlq package | grep -v '/$' | xargs -r du -h | sort -h

### 查找不属于任何软件包的文件

如果您的系统中有不属于任何软件包的零散文件（通常是由于您没有使用包管理器安装软件），您可能需要查找这些文件以清理它们。

一种方法是列出所有感兴趣的文件，并对照 pacman 进行检查：

    # (export LC_ALL=C.UTF-8; comm -13 <(pacman -Qlq | sed 's,/$,,' | sort) <(find /etc /usr /opt -path /usr/lib/modules -prune -o -print | sort))

提示：lostfiles包 脚本执行类似的步骤，但还包括一个广泛的黑名单，以从输出中删除常见的误报。

### 跟踪软件包创建的无主文件

多数系统将通过通常的操作过程慢慢的收集一些 ghost 文件，如状态文件、日志、索引等。

pacutils包 中的 `pacreport` 可用于通过 `/etc/pacreport.conf` 跟踪这些文件及其关联（见 pacreport(1) § FILES）。

一个例子可能看起来像这样（摘要）：

    /etc/pacreport.conf

    [Options]
    IgnoreUnowned = usr/share/applications/mimeinfo.cache

    [PkgIgnoreUnowned]
    alsa-utils = var/lib/alsa/asound.state
    bluez = var/lib/bluetooth
    ca-certificates = etc/ca-certificates/trust-source/*
    dbus = var/lib/dbus/machine-id
    glibc = etc/ld.so.cache
    grub = boot/grub/*
    linux = boot/initramfs-linux.img
    pacman = var/lib/pacman/local
    update-mime-database = usr/share/mime/magic

然后，当由 root 用户使用 `pacreport --unowned-files` 时，如果不再安装关联的软件包（或者如果已创建任何新文件），则会列出所有无主文件。

此外，aconfmgr（aconfmgr-gitAUR）允许使用配置脚本跟踪修改的和孤立的文件。

### 删除未使用的软件包（孤立软件包）

孤立软件包是作为依赖项安装的包，任何软件包都不再依赖它。

由于使用 `pacman -R package` 而不是 `pacman -Rs package` 卸载软件包，将软件包安装为 makedepends，或者软件包的较新版本中删除了依赖项，它们可能会随着时间的推移在您的系统上累积。

递归删除孤立软件包及其配置文件：

    # pacman -Qdtq | pacman -Rns -

如果没有孤立软件包，将显示错误 `错误：有参数 '-' 但标准输入流为空`。这个是正常的，因为 `pacman -Rns` 没有收到任何参数。可以通过在第二个命令前面加上来自 moreutils包 包的 ifne(1) 来避免该错误。

如果列出的软件包中有您不想删除的，可以通过将其标记为显式安装来将其从孤立软件包列表中排除：

    # pacman -D --asexplicit package

注意：`-Qt` 仅显示真的孤立包，要包含可选依赖，请使用 `-Qtt` .
提示：将 `pacman -Qdt` 添加到 pacman 的一个处理后钩子用于在如果有处理产生孤立包后获得提示。这在当有软件包被仓库放弃时是有用的，因为任何被抛弃的包都会成为本地的一个孤立包（除非它是被显式安装的）。要避免在没有找到孤立包时“执行命令失败”的错误，在你的钩子中为 `Exec` 使用如下的指令: `/usr/bin/bash -c "/usr/bin/pacman -Qdt || /usr/bin/echo '=> 未找到。'"` 软件包 pacman-log-orphans-hookAUR 使用类似的钩子提供了更详细的指示。

### 检测更多不需要的软件包

在某些情况下，上述方法不会检测到所有可能不需要的包。例如，依赖环（也称为“循环依赖”）、额外依赖（多次满足）、一些非显式的可选项等。

要检测此类包：

    $ pacman -Qqd | pacman -Rsu --print -

如果要一次删除列表中的所有包，请运行不带 `--print` 参数的命令。

### 删除必需的软件包以外的所有软件包

如果需要删除必需的软件包以外的所有软件包，一种方法是将非必需包的安装原因设置为依赖项，然后删除所有不必要的依赖项。

首先，对于所有“显式安装”的包，将其安装原因更改为“作为依赖项安装”：

    # pacman -D --asdeps $(pacman -Qqe)

然后，将您不想删除的必需软件包安装原因更改为“显式安装”，以避免将其作为目标：

    # pacman -D --asexplicit base linux linux-firmware

注意：

- 可以向上述命令中添加其他包，以避免被删除。请参阅安装指南#安装必需的软件包，以了解功能完备的基本系统可能需要的其他软件包的更多信息。
- 这还将引导加载程序选择为要删除的包。系统应该仍然可以启动，但如果没有它，启动参数可能无法更改。

最后，按照#删除未使用的软件包（孤立软件包）中的说明删除“作为依赖项安装”的所有包。

### 获取若干软件包的依赖项列表

依赖项按字母顺序排序，并删除重复项。

注意：要仅显示本地已安装软件包的树，使用 `pacman -Qi`。

    $ LC_ALL=C.UTF-8 pacman -Si packages | awk -F'[:<=>]' '/^Depends/ {print $2}' | xargs -n1 | sort -u

或者，用 expac包：

    $ expac -l '\n' %E -S packages | sort -u

### 列出已更改的备份文件

要列出被 pacman 跟踪的易被用户更改（即列在PKGBUILD backup 数组中的文件）且已被用户更改的文件，请使用以下命令：

    # pacman -Qii | awk '/\[modified\]/ {print $(NF - 1)}'

使用 root 权限运行此命令将确保输出中包含只能由 root 读取的文件（例如 `/etc/sudoers`）。

这可以用在执行选择性系统备份或尝试将系统配置从一台计算机复制到另一台计算机时。

提示：

- 见#列出软件包中所有被更改的文件以列出 pacman 知道的所有更改过的文件，而不仅仅是备份文件。
- 见#查找不属于任何软件包的文件以列出系统中未被 pacman 跟踪的所有文件。

### 备份 pacman 数据库

以下命令可用于备份本地 pacman 数据库：

    $ tar -cjf pacman_database.tar.bz2 /var/lib/pacman/local

将备份的 pacman 数据库文件存储在一个或多个脱机媒体上，如 U 盘、外部硬盘或 CD-R。

可以通过将 `pacman_database.tar.bz2` 文件移动到 `/` 目录并执行以下命令来恢复数据库：

    # tar -xjvf pacman_database.tar.bz2

注意：如果 pacman 数据库文件已损坏，并且没有可用的备份文件，此时重建 pacman 数据库还是有希望的。查阅#恢复 pacman 的本地数据库。
提示：pakbak-gitAUR 包提供了一个脚本和一个 systemd 服务来自动化任务。可以在 `/etc/pakbak.conf` 中进行配置。

### 简单的检查更改日志

当维护者更新软件包时，提交通常会以有用的方式进行注释。用户可以通过安装 pacologAUR 从命令行快速检查这些。通过 `pacolog package` 使用该实用程序列出来自官方软件库或 AUR 的包的最近提交消息。

## 安装和修复

获取和修复软件包的额外方法。

### 从 CD/DVD 或 U 盘安装软件包

本文或本章节可能需要合并到#自建本地仓库。

附注： Use as an example and avoid duplication（在 Talk:Pacman/提示和技巧 中讨论）

要下载软件包，或软件包组：

    # cd ~/Packages
    # pacman -Syw --cachedir . base base-devel grub-bios xorg gimp
    # repo-add ./custom.db.tar.zst ./*.pkg.tar.zst

Pacman 默认情况下将引用主机安装，但无法正确解析和下载现有的依赖项。在需要所有包和依赖项的情况下，建议创建一个临时空白数据库，并使用 `--dbpath` 引用它：

    # mkdir /tmp/blankdb
    # pacman -Syw --cachedir . --dbpath /tmp/blankdb base base-devel grub-bios xorg gimp
    # repo-add ./custom.db.tar.zst ./*.pkg.tar.zst

然后，您可以将“Packages”目录刻录到光盘（如 CD、DVD）或将其传输到U盘、外部硬盘等。

1. 挂载媒体：

对于光盘驱动器：

    # mount --mkdir /dev/sr0 /mnt/repo

对于 USB 闪存驱动器，硬盘驱动器等：

    # mount --mkdir /dev/sdxY /mnt/repo

2. 编辑 `pacman.conf` 并将此存储库添加到其他存储库（例如，extra、core 等）之前。这很重要。不要只取消对底部的注释。这样可以确保 CD/DVD/USB 中的文件优先于标准存储库中的文件：

    /etc/pacman.conf

    [custom]
    SigLevel = PackageRequired
    Server = file:///mnt/repo/Packages

3. 最后，同步 pacman 数据库，以便能够使用新的存储库：

    # pacman -Syu

### 自建本地仓库

使用 pacman 中包含的 repo-add 脚本为个人软件仓库生成数据库。请使用 `repo-add --help` 获取有关其用法的详细信息。 软件包数据库是一个可以压缩的 tar 文件。有效的扩展名为 .db 或 .files，后跟归档扩展名.tar, .tar.gz, .tar.bz2, .tar.xz, .tar.zst, 或 .tar.Z。文件不需要存在，但所有父目录都必须存在。

要向数据库中添加新包，或替换数据库中现有包的旧版本，请运行：

    $ repo-add /path/to/repo.db.tar.zst /path/to/package-1.0-1-x86_64.pkg.tar.zst

当使用 repo-add 时，数据库和包不需要位于同一目录中，但请记住，当和该数据库一起使用 pacman 时，它们应该在一起。将要加入仓库中的所有建好的包存储在一个目录中，还允许使用 shell glob 扩展一次添加或更新多个包：

    $ repo-add /path/to/repo.db.tar.zst /path/to/*.pkg.tar.zst

警告：repo-add 以与命令行上传递的顺序相同的顺序将条目添加到数据库中。如果涉及同一软件包的多个版本，必须小心确保最后添加正确的版本。特别注意，shell 使用的词法顺序取决于语言环境，并且不同于 pacman 使用的 vercmp(8) 顺序。

如果您希望支持多个架构，则应采取预防措施以防止发生错误。每个架构都应有自己的目录树：

    $ tree ~/customrepo/ | sed "s/$(uname -m)/arch/g"

    /home/archie/customrepo/
    └── arch
        ├── customrepo.db -> customrepo.db.tar.zst
        ├── customrepo.db.tar.zst
        ├── customrepo.files -> customrepo.files.tar.zst
        ├── customrepo.files.tar.zst
        └── personal-website-git-b99cce0-1-arch.pkg.tar.zst

    1 directory, 5 files

repo-add 可执行文件检查包软件是否适合。如果不是这样，您将遇到类似于以下内容的错误消息：

    ==> 错误： '/home/archie/customrepo/arch/foo-arch.pkg.tar.zst' 未包含有效的数据库存档扩展名。

repo-remove 用于从软件包数据库中删除包，命令行中只指定包名。

    $ repo-remove /path/to/repo.db.tar.zst pkgname

创建本地仓库数据库后，将仓库添加到要使用该仓库的每个系统的 `pacman.conf` 中。自定义仓库的一个示例在 `pacman.conf` 中。仓库的名称是省略了文件扩展名的数据库文件名。在上面的示例中，仓库名仅为 repo。使用 `file://` URL 或通过 HTTP 使用 `http://localhost/path/to/directory` 引用仓库的位置。

如果愿意，可以将自定义仓库添加到非官方用户仓库列表中，这样社区就可以从中受益。

### 在网络上共享 pacman 缓存

本文或本章节可能需要合并到Package_Proxy_Cache。

附注： Same topic（在 Talk:Pacman/提示和技巧 中讨论）

如果你碰巧在你的局域网上运行了几个 Arch boxes，你可以共享软件包，这样可以大大减少下载时间。请记住，你不应在不同的体系结构（即 i686 和 x86_64）之间共享，否则会遇到问题。

#### 只读缓存

Pacman 6.1.0 直接支持缓存服务器。缓存服务器将在任何非缓存服务器之前尝试，不会因为 HTTP 404 下载错误而从服务器池中移除，并且不会用于数据库文件。

如果您正在寻找快速解决方案，只需运行基本临时网络服务器，其他计算机可以将其用作缓存服务器。

使用 Python http.server 模块开始提供此目录：

    $ python -m http.server -d /var/cache/pacman/pkg/

提示：默认情况下，Python `http.server` 会监听任何接口的端口 `8000`。要使用其他端口或仅绑定到特定地址，只需添加一个参数和另一个参数：

    $ python -m http.server -d /var/cache/pacman/pkg/ --bind 127.0.0.1 8080

然后在每台客户机上编辑 `/etc/pacman.d/mirrorlist`，将此服务器添加为缓存服务器：

    /etc/pacman.d/mirrorlist

    CacheServer = http://server-ip:port

警告：不要像其他条目一样将 `/repos/$repo/os/$arch` 追加到该自定义服务器，因为该层次结构不存在，因此查询将失败。

如果要寻找更独立的解决方案，darkhttpd包 提供了一个最小的网络服务器。将以前的 `python` 命令替换为如：

    [http]$ darkhttpd /var/cache/pacman/pkg --no-server-id

为了方便，您还可以将 darkhttpd 作为 systemd 服务运行：见 systemd#编写单元文件。

miniserve包，一个用 Rust 编写的小型网络服务器，也可以使用：

    $ miniserve /var/cache/pacman/pkg

然后像上面一样编辑 `/etc/pacman.d/mirrorlist`，让 url 位于第一位。

如果您已经在为其他用途运行网络服务器，您可能希望将其重新用作本地仓库服务器。例如，如果您已经使用 nginx 服务于某个站点，则可以在端口8080上添加 nginx server 块侦听：

    /etc/nginx/nginx.conf

    server {
        listen 8080;
        root /var/cache/pacman/pkg;
        server_name myarchrepo.localdomain;
        try_files $uri $uri/;
    }

进行此更改后，记得重启 `nginx.service`。

提示：无论您使用哪种网络服务器，请确保防火墙配置（若有）允许所需流量访问所配置的端口，并且不允许任何不希望的流量。见 安全#网络与防火墙。

#### 层叠挂载只读缓存

通过层叠挂载（英语：Overlay filesystem）其 `/var/cache/pacman/pkg` 目录，可以将本地网络上的一台机器用作只读包缓存。如果该服务器已在其上安装了其他 boxes 也使用的合理全面的最新软件包，则这种配置是有利的。这对于在低带宽上游的连接末端维护多台机器非常有用。

例如，要使用此方法：

    # mkdir /tmp/remote_pkg /mnt/workdir_pkg /tmp/pacman_pkg
    # sshfs remote_username@remote_pkgcache_addr:/var/cache/pacman/pkg /tmp/remote_pkg -C
    # mount -t overlay overlay -o lowerdir=/tmp/remote_pkg,upperdir=/var/cache/pacman/pkg,workdir=/mnt/workdir_pkg /tmp/pacman_pkg

注意：工作目录必须是与上级目录位于同一挂载设备上的空目录。见 层叠文件系统#使用（英语：Overlay filesystem#Usage）。
提示：如果列出 `/tmp/pacman_pkg` 层叠目录会出现错误，例如“Stale file handle”，请尝试使用选项 `-o redirect_dir=off -o index=off` 进行层叠挂载。

在之后，使用选项 `--cachedir /tmp/pacman_pkg` 运行 pacman，例如：

    # pacman -Syu --cachedir /tmp/pacman_pkg

#### 分布式只读缓存

有一些特定于 Arch 的工具可以自动发现网络上的其他计算机，并提供包缓存。尝试 pacredir包, pacserve（英语：pacserve）, pkgdistcacheAUR, 或 paclanAUR。pkgdistcache 使用 Avahi 而不是普通 UDP，这可能在某些家庭网络中更好地工作，这些家庭网络在 Wi-Fi 和以太网之间路由而不是桥接。

从历史上看，有 PkgD 和 multipkg，但它们都已不再维护。

#### 读写缓存

为了在多台计算机之间共享软件包，只需使用任何基于网络的挂载协议共享 `/var/cache/pacman/`。本章节介绍如何使用 SSHFS 在同一本地网络上的多台计算机之间共享包缓存和相关库目录。请记住，网络共享缓存可能会很慢，这取决于文件系统的选择以及其他因素。

首先，安装任何基于网络的文件系统软件包：sshfs包, curlftpfs包, samba包 或 nfs-utils包。

提示：

- 要使用 sshfs，请考虑阅读使用 SSH 密钥。
- 默认情况下，smbfs 不提供包含冒号的文件名，这会导致客户机重新下载有问题的包。若要防止这种情况，请在客户端上使用 `mapchars` 挂载选项。

然后，要共享实际的软件包，请在每台客户机上从服务器挂载 `/var/cache/pacman/pkg` 到 `/var/cache/pacman/pkg`。

警告：不要将 `/var/cache/pacman/pkg` 或其任何祖先（例如，`/var`）设置为符号链接。Pacman 希望这些是目录。当 pacman 重新安装或升级自己时，它将删除符号链接并创建空目录。然而，在事务 pacman 期间，依赖于驻留在那里的一些文件，因此中断更新过程。更多信息请查阅 FS#50298。

#### 使用 rsync 或 FTP 双向同步

本地环境中的另一种方法是 rsync。选择用于缓存的服务器并启用 rsync 守护程序。在客户端上，通过 rsync 协议与此共享进行双向同步。包含冒号的文件名对于 rsync 协议来说没有问题。

为客户端起草示例，在共享名称中使用 `uname -m` 可确保依赖于架构的同步：

    # rsync ... rsync://server/share_$(uname -m)/ /var/cache/pacman/pkg/
    # pacman -Syu
    # paccache --remove --keep 3
    # rsync --delete ... /var/cache/pacman/pkg/ rsync://server/share_$(uname -m)/

如果不依赖未加密的 rsync 守护程序，更安全的选择是通过 ssh 使用 rsync，Rsync#使用 SSH 自动备份提供了概述。

如果 rsync 在您的本地环境中不可用，简单的 ftp 服务也适合双向同步。lftp包 提供了 `--mirror` 和 `--delete` 选项来同步本地和远程存储。

#### 使用 nginx 的动态反向代理缓存

nginx 可用于将软件包请求代理到官方上游镜像，并将结果缓存到本地磁盘。该软件包的所有后续请求将直接从本地缓存提供，从而最大限度地减少更新大量计算机所需的互联网流量。

在本例中，缓存服务器将在 `http://cache.domain.example:8080/` 上运行并将软件包存储在 `/srv/http/pacman-cache/` 中。

在将托管缓存的计算机上安装 nginx。为缓存创建目录并调整权限，以便 nginx 可以向其中写入文件：

    # mkdir /srv/http/pacman-cache
    # chown http:http /srv/http/pacman-cache

使用 nginx pacman 缓存配置作为 `/etc/nginx/nginx.conf` 的起点。检查 `resolver` 指令是否适合您的需要。在上游 server 块中，使用官方镜像的地址配置 `proxy_pass` 指令，请参阅配置文件中有关期待的格式的示例。一旦您对配置文件感到满意就启动并启用 nginx。

为了使用缓存，每个 Arch Linux 计算机（包括托管缓存的计算机）必须在 `mirrorlist` 文件的顶部具有以下行：

    /etc/pacman.d/mirrorlist

    Server = http://cache.domain.example:8080/$repo/os/$arch
    ...

注意：您需要创建一个方法来清除旧包，因为缓存目录会随着时间的推移而不断增长。`paccache`（由 pacman-contrib包 提供）可用于使用您选择的保留标准自动执行此操作。例如，`find /srv/http/pacman-cache/ -type d -exec paccache -v -r -k 2 -c {} \;` 将在缓存目录中保留最后两个版本的包。

#### Pacoloco 代理缓存服务器

Pacoloco 是一个易于使用的 pacman 仓库代理缓存服务器。它还允许自动预取缓存的包。

安装它为 pacoloco包。打开配置文件并添加 pacman 镜像：

    /etc/pacoloco.yaml

    port: 9129
    repos:
      mycopy:
        urls:
          - http://mirror.lty.me/archlinux
          - http://mirrors.kernel.org/archlinux

重启 `pacoloco.service`，代理仓库将在 `http://myserver:9129/repo/mycopy`。

#### Flexo 代理缓存服务器

Flexo 是 pacman 仓库的另一个代理缓存服务器。Flexo 由 flexo-gitAUR 提供。安装后，启动 `flexo.service` 单元。

默认情况下，Flexo 在端口 `7878` 上运行。在 `/etc/pacman.d/mirrorlist` 的顶部加入 `Server = http://myserver:7878/$repo/os/$arch`，以便 pacman 通过 Flexo 下载软件包。

#### 使用同步程序同步 pacman 软件包缓存

使用 Syncthing（英语：Syncthing） 或 Resilio Sync（英语：Resilio Sync） 以同步 pacman 缓存目录（即 `/var/cache/pacman/pkg`）。

#### 避免过度清理缓存

执行 `pacman -Sc` 清理软件包缓存时，会删除所有当前机器上未安装的软件包。由于 pacman 无法判断软件包是否在其他机器上安装，这会导致移除某些还需要的软件包。

要在清理缓存时只删除过时的 tarballs：

    /etc/pacman.conf

    [options]
    CleanMethod = KeepCurrent

### 从文件系统重新创建软件包

要从文件系统重新创建软件包，请使用 fakepkgAUR。系统中的文件按原样保存，因此任何修改都将出现在装配的软件包中。因此，不鼓励分发重新创建的包；有关替代方案，请参见 Arch 构建系统和 Arch Linux Archive。

### 已安装软件包的列表

保留所有明确安装的软件包的列表对于备份系统或加快新的安装非常有用：

    $ pacman -Qqe > pkglist.txt

注意：

- 加上选项 `-t`，其他明确安装的软件包依赖的软件包不会被提及。如果从此列表中重新安装，它们将仅作为依赖项被安装。
- 加上选项 `-n`，将在列表中省略外部包（例如来自Arch 用户软件仓库 (AUR)）。
- 使用 `comm -13 <(pacman -Qqdt | sort) <(pacman -Qqdtt | sort) > optdeplist.txt` 还可以创建一个已安装的可选依赖项列表，这些依赖项可以使用 `--asdeps` 重新安装。
- 使用 `pacman -Qqem > foreignpkglist.txt` 创建已明确安装的 AUR 和其他外部包的列表。

要保持明确安装的软件包的最新列表（例如与版本化的 `/etc/` 结合），可以设置钩子。例子：

    [Trigger]
    Operation = Install
    Operation = Remove
    Type = Package
    Target = *

    [Action]
    When = PostTransaction
    Exec = /bin/sh -c '/usr/bin/pacman -Qqe > /etc/pkglist.txt'

### 从列表安装软件包

要从以前保存的软件包列表中安装软件包，而不重新安装已经安装的已更新的软件包，请运行：

    # pacman -S --needed - < pkglist.txt

然而，列表中可能存在来自 AUR 或本地安装的外部软件包。要从列表中筛选出外部包，可以如下丰富前面的命令行：

    # pacman -S --needed $(comm -12 <(pacman -Slq | sort) <(sort pkglist.txt))

最后，要确保系统中安装的软件包与列表匹配，并删除列表中未提及的所有软件包：

    # pacman -Rsu $(comm -23 <(pacman -Qq | sort) <(sort pkglist.txt))

提示：这些任务可以自动化。有关示例，请参见 bacpacAUR, packupAUR, pacmanityAUR, 和 pugAUR。

### 列出软件包中所有被更改的文件

如果您怀疑文件损坏（例如，由于软件/硬件故障），但不确定文件是否损坏，您可能需要与包中的哈希值进行比较。这可以通过 pacutils包：

    # paccheck --sha256sum --quiet

有关数据库的恢复，请见#恢复 pacman 的本地数据库。`mtree` 文件也可以从相应的软件包文件中提取为 `.MTREE`。

注意：当怀疑存在恶意更改时，不要按原样使用！在这种情况下，建议采取安全防范措施，例如使用 live 介质和独立的哈希值源。

### 重新安装所有软件包

要重新安装所有本地软件包，使用：

    # pacman -Qqn | pacman -S -

外来（AUR）软件包必须单独重新安装；您可以使用 `pacman -Qqm` 列出它们。

Pacman 默认保留安装原因。

警告：要强制覆盖所有包，请使用 `--overwrite=*`，尽管这应该是绝对的最后手段。请见系统维护#避免某些 pacman 命令。

### 恢复 pacman 的本地数据库

见 pacman/Restore local database。

### 从已有安装修复 USB 系统

如果你有一个 Arch 安装在U盘上，不小心搞坏了（比如，写入U盘时断电了），可以使用主机上的 Arch 修复U盘上的 Arch（假设U盘挂载在 `/newarch`）：

    # pacman -S $(pacman -Qq --dbpath /newarch/var/lib/pacman) --root /newarch --dbpath /newarch/var/lib/pacman

### 查看 .pkg 文件中的单个文件

例如，如果您想查看 systemd包 包中提供的 `/etc/systemd/logind.conf` 的内容：

    $ bsdtar -xOf /var/cache/pacman/pkg/systemd-250.4-2-x86_64.pkg.tar.zst etc/systemd/logind.conf

或者您可以使用 vim包 浏览归档：

    $ vim /var/cache/pacman/pkg/systemd-250.4-2-x86_64.pkg.tar.zst

### 查找使用旧软件包中的库的应用程序

运行中的进程不会自动注意到由更新引起的更改。相反，它们继续使用旧的库版本。由于与安全漏洞或其他 bug 相关的潜在问题以及版本不兼容性，这可能是不可取的。

依赖于更新的库的进程可以使用 htop包 来找到，htop包 会突出显示受影响程序的名称，或者使用基于 lsof包 的代码片段，该代码片段还会打印库的名称：

    # lsof +c 0 | grep -w DEL | awk '1 { print $1 ": " $NF }' | sort -u

此解决方案一般将仅检测由运行中进程打开的文件，这基本上将其限制为共享库（`.so` 文件）。它可能会丢失一些依赖关系，例如 Java 或 Python 应用程序的依赖关系。

### 仅安装所需语言的内容

许多软件包会安装多种语言的文档和翻译。有些程序旨在删除这些不必要的文件，例如 localepurgeAUR，它在安装包后运行以删除不需要的区域设置文件。更直接的方法是通过 `/etc/pacman.conf` 中的 `NoExtract` 指令提供的，该指令可以防止这些文件被安装。

注意：如 Pacman#跳过文件安装到系统 中所述，“后面的规则会覆盖前面的规则，并且可以通过在规则前添加 `!` 来否定规则。”

要防止安装所有帮助文件的翻译，除了 C 区域设置外，请添加：

    NoExtract = usr/share/help/* !usr/share/help/C/*

要防止安装所有 HTML 文档，请添加：

    NoExtract = usr/share/gtk-doc/html/*
    NoExtract = usr/share/doc/HTML/*

警告：一些用户注意到，删除所有区域设置会导致 dmenu, Steam, 甚至 Xorg 的意外结果。以下示例已进行调整，以避免此类问题，仅安装英文（US）文件和所需的 C 区域设置。

要防止安装各种 locale，除了所需的区域设置外，请添加：

    NoExtract = usr/share/locale/* usr/share/X11/locale/*/* usr/share/i18n/locales/* opt/google/chrome/locales/* !usr/share/X11/locale/C/*
    NoExtract = !usr/share/X11/locale/compose.dir !usr/share/X11/locale/iso8859-1/*
    NoExtract = !*locale*/en*/* !usr/share/*locale*/locale.*
    NoExtract = !usr/share/*locales/en_?? !usr/share/*locales/i18n* !usr/share/*locales/iso*
    NoExtract = usr/share/i18n/charmaps/* !usr/share/i18n/charmaps/UTF-8.gz !usr/share/i18n/charmaps/ANSI_X3.4-1968.gz
    NoExtract = !usr/share/*locales/trans*
    NoExtract = !usr/share/*locales/C !usr/share/*locales/POSIX

要防止安装翻译的 man page，请添加：

    NoExtract = usr/share/man/* !usr/share/man/man*

要防止安装 vim-runtime包 中的语言文件，请添加：

    NoExtract = usr/share/vim/vim*/lang/*

要防止安装 Qt 应用程序中除英文内容外的所有内容，请添加：

    NoExtract = usr/share/*/translations/*.qm usr/share/*/nls/*.qm usr/share/qt/phrasebooks/*.qph usr/share/qt/translations/*.pak !*/en-US.pak

要防止安装 Electron 应用程序中除英文内容外的所有内容，请添加：

    NoExtract = usr/share/*/locales/*.pak opt/*/locales/*.pak usr/lib/*/locales/*.pak !*/en-US.pak

要防止安装 LibreOffice 中的英文帮助文件，请添加：

    NoExtract = usr/lib/libreoffice/help/en-US/*

要防止安装 OnlyOffice 中除英文内容外的所有内容，请添加：

    NoExtract = opt/onlyoffice/desktopeditors/dictionaries/* !opt/onlyoffice/desktopeditors/dictionaries/en_US/*
    NoExtract = opt/onlyoffice/desktopeditors/editors/web-apps/apps/*/main/locale/* !*/en.json
    NoExtract = opt/onlyoffice/desktopeditors/editors/web-apps/apps/*/main/resources/help/*/* !*/help/en/*
    NoExtract = opt/onlyoffice/desktopeditors/editors/web-apps/apps/*/main/resources/symboltable/* !*/en.json
    NoExtract = opt/onlyoffice/desktopeditors/editors/web-apps/apps/documenteditor/forms/locale/* !*/en.json
    NoExtract = opt/onlyoffice/desktopeditors/editors/web-apps/apps/spreadsheeteditor/main/resources/formula-lang/* !*/en.json !*/en_desc.json
    NoExtract = opt/onlyoffice/desktopeditors/converter/empty/*/* !opt/onlyoffice/desktopeditors/converter/empty/en-US/*
    NoExtract = opt/onlyoffice/desktopeditors/converter/templates/*/* !opt/onlyoffice/desktopeditors/converter/templates/EN/*

要防止安装除英文 iBus 表情符号字典外的所有内容，请添加：

    NoExtract = usr/share/ibus/dicts/emoji-*.dict !usr/share/ibus/dicts/emoji-en.dict

### 在不良连接上安装软件包

当试图从不良连接（例如在火车使用手机网络）安装软件包时，请使用 `--disable-download-timeout` 选项来减少接收错误的可能性，例如：

    error: failed retrieving file […] Operation too slow. Less than 1 bytes/sec transferred the last 10 seconds

或

    error: failed retrieving file […] Operation timed out after 10014 milliseconds with 0 out of 0 bytes received

## 性能

本文或本节内容已经过时。

原因： 本页是在 pacman 原生支持并行下载之前编写的，并且应该提到，由于 pacman v6 版本，这不再是一次下载多个软件包的唯一选项。 (在Talk:Pacman/提示和技巧讨论)

### 下载速度

下载软件包时 pacman 按照 `/etc/pacman.d/mirrorlist` 的顺序使用镜像。默认情况下位于列表顶部的镜像可能不是最快的。要选择更快的镜像，请见镜像源。

Pacman 下载软件包的速度也可以通过启用并行下载来提高，或者通过使用不同的应用程序来下载软件包，而不是使用 pacman 内建的文件下载器。

不论怎样，在做任何修改前，你必须确定拥有了最新版的 pacman。

    # pacman -Syu

#### Powerpill

Powerpill 是 pacman 的包裹程序，增加了平行下载和分段下载功能，加速下载过程。

#### wget

参见 wget#pacman 集成。

对于需要更强大代理设置的用户来说，用 wget 比用 pacman 内建的下载方式更加方便。

要使用 `wget`，首先安装 wget包 软件包，然后修改 `/etc/pacman.conf` 并在其中的 `[options]` 区段将下面内容去掉注释：

    XferCommand = /usr/bin/wget --passive-ftp --show-progress -c -q -N %u

除了将 `wget` 参数放在 `/etc/pacman.conf` 里，你也可以直接修改 `wget` 配置文件（全局文件是 `/etc/wgetrc`，各个用户的文件是 `$HOME/.wgetrc`）。

#### aria2

aria2 是一个具有断点续传和分块下载功能的轻量级下载软件，支持 HTTP/HTTPS/FTP 协议。aria2 可以多线程通过 HTTP/HTTPS 和 FTP 协议连接镜像服务器，显著提高下载速度。

注意：在 pacman 的 XferCommand 使用 aria2c 不会导致并行下载多个包。因为 Pacman 调用 XferCommand 时是一次一个包调用的，等待下载完成才会启动下一个。想要并行下载多个包，参见 Powerpill。

安装 aria2包，修改 `/etc/pacman.conf`，在 `[options]` 段添加下列一行：

    XferCommand = /usr/bin/aria2c --allow-overwrite=true --continue=true --file-allocation=none --log-level=error --max-tries=2 --max-connection-per-server=2 --max-file-not-found=5 --min-split-size=5M --no-conf --remote-time=true --summary-interval=60 --timeout=5 --dir=/ --out %o %u

提示：使用 pacman 和 aria2 的另一种配置]试图简化配置并添加更多配置选项。

关于使用的 aria2c 选项，见 aria2c(1) § OPTIONS。

- `-d, --dir`由 pacman 设定的文件下载目录。
- `-o, --out`: 输出的下载文件的文件名。
- `%o`: 代表 pacman 指定的本地文件名的变量。
- `%u`: 代表 pacman 指定的下载 URL 的变量。

#### 其它程序

这里还有一些可以和 pacman 协同工作的下载软件。下面列举了它们对应的 XferCommand 命令写法：

- `snarf`: `XferCommand = /usr/bin/snarf -N %u`
- `lftp`: `XferCommand = /usr/bin/lftp -c pget %u`
- `axel`: `XferCommand = /usr/bin/axel -n 2 -v -a -o %o %u`
- `hget`: `XferCommand = /usr/bin/hget %u -n 2 -skip-tls false`（请阅读 Github 项目页面上的文档获取更多信息）
- `saldl`: `XferCommand = /usr/bin/saldl -c6 -l4 -s2m -o %o %u`（请阅读项目页面上的文档获取更多信息）

## 工具

- isfree — 一个 Bash 脚本，用于列出非自由软件包。基于 Parabola 的黑名单。

  https://github.com/leo-arch/isfree || isfreeAUR

- Lostfiles — 标识不属于任何包的文件的脚本。

  https://github.com/graysky2/lostfiles || lostfiles包

- pacutils — 基于 libalpm 的程序的帮手库。

  https://github.com/andrewgregory/pacutils || pacutils包

- pkgfile — 查找包拥有文件的工具。

  https://github.com/falconindy/pkgfile || pkgfile包

- pkgtop — 为 GNU/Linux 设计的交互式包管理器和资源监视器。

  https://github.com/orhun/pkgtop || pkgtop-gitAUR

- Powerpill — 通过 aria2 和 Reflector 使用并行和分段下载来尝试加快 pacman 的下载速度。

  https://xyne.dev/projects/powerpill/ || powerpillAUR

- repoctl — 帮助管理本地仓库的工具。

  https://github.com/cassava/repoctl || repoctlAUR

- repose — Arch Linux 仓库构建工具。

  https://github.com/vodik/repose || repose包

- snap-pac — 使 pacman 自动使用 snapper 创建前/后快照，类似 openSUSE 的 YaST。

  https://github.com/wesbarnett/snap-pac || snap-pac包

- vrms-arch — 一个虚拟的 Richard M. Stallman 告诉你安装了哪些非自由软件包。

  https://github.com/orospakr/vrms-arch || vrms-arch-gitAUR

分类：​

- 包管理器
- 使用“模板:过时”标记的页面或章节

隐藏分类：​

- 使用“模板:合并”标记的页面或章节

pacman/提示和技巧
添加话题