pacman/Pacnew 和 Pacsave
当 pacman 移除一个包含配置文件的软件包时,通常会创建该配置文件的备份副本,并在文件名后附加 .pacsave。同样地,当 pacman 升级一个软件包,并且该软件包包含一个由维护者创建的新配置文件,该文件与当前安装的文件不同时,pacman 会保存一个 .pacnew 文件,其中包含新的配置。当这些文件被写入时,pacman 会发出通知。
为什么创建这些文件
.pacnew 文件可能在软件包升级期间(pacman -Syu
、pacman -Su
或 pacman -U
)创建,以避免覆盖已存在且先前被用户修改的文件。当这种情况发生时,pacman 的输出中将出现类似以下的消息
warning: /etc/pam.d/usermod installed as /etc/pam.d/usermod.pacnew
.pacsave 文件可能在软件包移除期间(pacman -R
),或通过软件包升级(必须先移除软件包)创建。当 pacman 数据库记录到软件包拥有的某个文件应该被备份时,它将创建一个 .pacsave 文件。当这种情况发生时,pacman 会输出类似以下的消息
warning: /etc/pam.d/usermod saved as /etc/pam.d/usermod.pacsave
这些文件需要用户手动干预,最佳实践是在每次软件包升级或移除后立即处理它们。如果未处理,不正确的配置可能导致软件功能异常或软件完全无法运行。
软件包备份文件
软件包的 PKGBUILD 文件指定了在软件包升级或移除时应保留或备份哪些文件。例如,pulseaudio 的 PKGBUILD 包含以下行
backup=(etc/pulse/{daemon.conf,default.pa,system.pa})
安装后,可以使用 pacman -Qii package_name
从 pacman 数据库查询此列表。
要防止任何软件包覆盖特定文件,请参阅 Pacman#Skip file from being upgraded。
类型解释
.pacnew
对于每个正在升级的 #软件包备份文件,pacman 会交叉比较从文件内容生成的三个 md5sum:一个用于软件包最初安装的版本,一个用于文件系统中当前存在的版本,以及一个用于新软件包中的版本。如果文件系统中当前文件的版本已从软件包最初安装的版本修改过,pacman 无法知道如何将这些更改与新版本的文件合并。因此,在升级时,pacman 不会覆盖已修改的文件,而是将新版本保存为 .pacnew 扩展名,并保持已修改的版本不变。
更详细地说,三向 MD5 校验和比较会产生以下结果之一
- 原始 = X,当前 = X,新 = X
- 文件的所有三个版本的内容都相同,因此覆盖不是问题。将当前版本覆盖为新版本,并且不通知用户(尽管文件内容相同,但此覆盖将更新文件系统关于文件的安装、修改和访问时间的信息,并确保应用任何文件权限更改)。
- 原始 = X,当前 = X,新 = Y
- 当前版本的内容与原始版本相同,但新版本不同。由于用户未修改当前版本,并且新版本可能包含改进或错误修复,因此将当前版本覆盖为新版本,并且不通知用户。这是 pacman 能够执行的唯一自动合并新更改。
- 原始 = X,当前 = Y,新 = X
- 原始软件包和新软件包都包含完全相同版本的文件,但文件系统中当前的版本已被修改。保留当前版本,并丢弃新版本,不通知用户。
- 原始 = X,当前 = Y,新 = Y
- 新版本与当前版本相同。将当前版本覆盖为新版本,并且不通知用户(尽管文件内容相同,但此覆盖将更新文件系统关于文件的安装、修改和访问时间的信息,并确保应用任何文件权限更改)。
- 原始 = X,当前 = Y,新 = Z
- 所有三个版本都不同,因此保留当前版本,将新版本安装为 .pacnew 扩展名,并警告用户有关新版本的信息。用户需要手动将新版本中的任何必要更改合并到当前版本中。
极少数情况下,当升级后的软件包包含先前版本没有的备份文件时,情况会正确处理为 X/Y/Y 或 X/Y/Z,其中 X 是一个不存在的值。
.pacsave
如果用户修改了 backup
中指定的文件之一,则该文件将被重命名为 .pacsave 扩展名,并在软件包的其余部分被移除后保留在文件系统中。
-n
选项与 pacman -R
一起使用将导致完全移除指定软件包中的所有文件,因此不会创建 .pacsave 文件。定位 .pac* 文件
Pacman 不会自动处理 .pacnew 文件:您必须自行维护这些文件。下一节将介绍一些工具。要手动执行此操作,您首先需要定位它们。当升级或移除大量软件包时,可能会遗漏更新的 .pac* 文件。要发现是否已安装任何 .pac* 文件,请使用以下方法之一
- 要在
/etc
中搜索,其中存储了大多数全局配置# find /etc -name '*.pacnew' -o -name '*.pacsave'
或者在整个磁盘中搜索,将上述命令中的/etc
替换为/
(在这种情况下,您可能需要有选择地跳过某些目录以加快搜索速度)。 - 如果已安装,也可以使用 locate。首先重新索引数据库
# updatedb
然后运行$ locate --existing '*.pacnew' '*.pacsave'
- 使用 pacman 的日志查找它们
$ grep '\.pacnew\|\.pacsave' /var/log/pacman.log
请注意,日志不会跟踪当前文件系统中存在的文件,也不会跟踪已移除的文件;上述命令将列出您的系统中曾经存在的所有 .pac* 文件。为了仅获取最近 10 个 .pac* 文件,请将结果通过管道传递给tail
。
管理 .pac* 文件
pacdiff
pacman-contrib 提供了简单的 pacdiff(8) 工具,用于管理 .pac* 文件。
它将搜索 .pacnew、.pacsave 和 .pacorig 文件,然后提示您对其执行操作。
默认情况下,它使用 --pacmandb
,以使用当前已安装软件包的 backup
数组信息进行搜索。如果这不足以满足您的用例,您可以指定 --find
或 --locate
代替,以进行更彻底的搜索。
默认情况下,它使用 vimdiff,但您可以使用 DIFFPROG=your_editor pacdiff
指定不同的工具。有关其他常见的比较工具,请参阅 List of applications/Utilities#Comparison, diff, merge。
第三方实用程序
有一些第三方实用程序可用于这些任务,提供不同程度的自动化
- dotpac — 基本交互式脚本,具有基于 ncurses 的文本界面和有用的演练。没有合并或自动合并功能。
- etc-update — Gentoo 的实用程序,与其他发行版(包括 Arch)兼容。它提供了一个简单的 CLI 来查看、合并和交互式编辑更改。琐碎的更改(例如注释)可以自动合并。
- p3wm — 三向合并 .pacnew 文件。它可以自动合并琐碎的更改。如果发生冲突,它将启动 vimdiff、meld 或 kdiff3 来解决它们。
- pacnews-git — 一个简单的脚本,旨在查找所有 .pacnew 文件,然后使用 vimdiff 编辑它们。
- pacfiles-mode — 用于 Emacs 的软件包,用于管理和合并 .pacnew 文件。
- https://github.com/UndeadKernel/pacfiles-mode || available in melpa
- pacdiff-pacman-hook-git — Pacman 钩子,用于自动运行 pacdiff。
参见
- 论坛主题:处理 .pacnew 文件