pacman/Pacnew 与 Pacsave
当 pacman 移除一个包含配置文件(configuration file)的软件包时,它通常会创建该配置文件的一个备份副本,并在文件名后追加 .pacsave。同样,当 pacman 升级一个包含由维护者创建的、与当前安装文件不同的新配置文件时,它会保存一个 .pacnew 文件。pacman 在写入这些文件时会提供通知。
这些文件是如何创建的
在软件包升级(pacman -Syu, pacman -Su 或 pacman -U)期间可能会创建 .pacnew 文件,以避免覆盖一个已存在且先前被用户修改过的文件。发生这种情况时,pacman 的输出中会出现类似如下的消息:
warning: /etc/pam.d/usermod installed as /etc/pam.d/usermod.pacnew
在软件包移除(pacman -R)或软件包升级(需要先移除软件包)过程中,可能会创建 .pacsave 文件。当 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#跳过升级文件。
文件类型说明
.pacnew
对于正在升级的每个 #软件包备份文件,pacman 会交叉比较从文件内容生成的三个 md5sum:一个用于软件包最初安装的版本,一个用于当前文件系统中的版本,以及一个用于新软件包中的版本。如果当前文件系统中的文件版本与软件包最初安装的版本不同,pacman 将无法知道如何将这些更改与新版本的文件合并。因此,在升级时,pacman 不会覆盖已修改的文件,而是将新版本保存为 .pacnew 扩展名,并保持已修改的版本不变。
更详细地说,三向 MD5 校验和比较会导致以下结果之一:
- original = X, current = X, new = X
- 文件的所有三个版本内容相同,因此覆盖不是问题。用新版本覆盖当前版本,并且不通知用户(尽管文件内容相同,但此覆盖将更新文件系统中关于文件的安装、修改和访问时间的[1]信息,并确保应用任何文件权限更改)。
- original = X, current = X, new = Y
- 当前版本的内容与原始版本相同,但新版本不同。由于用户尚未修改当前版本,且新版本可能包含改进或错误修复,因此用新版本覆盖当前版本,并且不通知用户。这是 pacman 唯一能够执行的自动合并新更改的操作。
- original = X, current = Y, new = X
- 原始软件包和新软件包都包含完全相同版本的文件,但当前文件系统中的版本已被修改。将当前版本保留在原位,并丢弃新版本,不通知用户。
- original = X, current = Y, new = Y
- 新版本与当前版本相同。用新版本覆盖当前版本,并且不通知用户(尽管文件内容相同,但此覆盖将更新文件系统中关于文件的安装、修改和访问时间的[1]信息,并确保应用任何文件权限更改)。
- original = X, current = Y, new = Z
- 所有三个版本都不同,因此将当前版本保留在原位,将新版本安装为 .pacnew 扩展名,并警告用户新版本。预计用户将手动将新版本中的任何必要更改合并到当前版本中。
很少情况下,当升级后的软件包包含一个之前版本没有的备份文件时,这种情况会被正确处理为 X/Y/Y 或 X/Y/Z,其中 X 是一个不存在的值。
.pacsave
如果用户修改了 backup 中指定的文件,则该文件将被重命名为 .pacsave 扩展名,并在软件包其余部分被移除后保留在文件系统中。
pacman -R 使用 -n 选项将导致指定软件包的*所有*文件被完全移除,因此不会创建 .pacsave 文件。查找 .pac* 文件
Pacman 不会自动处理 .pacnew 文件:您必须自己维护它们。下一节将介绍一些工具。要手动执行此操作,您首先需要找到它们。在升级或移除大量软件包时,可能会错过更新的 .pac* 文件。要确定是否安装了任何 .pac* 文件,请使用以下方法之一:
- 要在存储大多数全局配置的
/etc中进行搜索:# find /etc -name '*.pacnew' -o -name '*.pacsave'
或者搜索整个磁盘(将上面的命令中的/etc替换为/)(在这种情况下,您可能需要 选择性地跳过某些目录 来加快搜索速度)。 - 如果已安装,也可以使用 locate。首先重新索引数据库:
# updatedb
然后运行:$ locate --existing --regex '.*\.(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 指定不同的工具。有关其他常用比较工具,请参阅 应用程序/实用程序列表#比较、diff、合并。
第三方工具
有一些第三方实用程序提供不同程度的自动化来完成这些任务:
- dotpac — 基本的交互式脚本,具有基于 ncurses 的文本界面和有用的向导。没有合并或自动合并功能。
- etc-update — Gentoo 的实用程序,与包括 Arch 在内的其他发行版兼容。它提供了一个简单的 CLI 来查看、合并和交互式编辑更改。微小的更改(如注释)可以自动合并。
- p3wm — 三向合并 .pacnew 文件。它可以自动合并微小的更改。如果发生冲突,它将启动 vimdiff、meld 或 kdiff3 来解决它们。
- pacnews-git — 一个旨在查找所有 .pacnew 文件,然后使用 vimdiff 编辑它们的简单脚本。
- pacfiles-mode — 一个用于 Emacs 的包,用于管理和合并 .pacnew 文件。
- pacdiff-pacman-hook-git — Pacman hook,用于自动运行 pacdiff。
参见
- 论坛帖子:处理 .pacnew 文件