pacman/Pacnew 和 Pacsave
当 pacman 移除一个含有配置文件的软件包时,通常会创建该配置文件的备份副本,并在文件名后追加 .pacsave。同样地,当 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#跳过文件升级。
类型详解
.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
指定不同的工具。有关其他常见比较工具,请参阅 应用程序列表/实用程序#比较、差异、合并。
第三方实用程序
一些第三方实用程序提供了针对这些任务的各种自动化级别
- dotpac — 带有基于 ncurses 的文本界面的基本交互式脚本和有用的演练。没有合并或自动合并功能。
- etc-update — Gentoo 的实用程序,与其他发行版(包括 Arch)兼容。它提供了一个简单的 CLI 来查看、合并和交互式编辑更改。简单的更改(例如注释)可以自动合并。
- p3wm — 三向合并 .pacnew 文件。它可以自动合并简单的更改。如果发生冲突,它将启动 vimdiff、meld 或 kdiff3 来解决冲突。
- pacnews-git — 一个旨在查找所有 .pacnew 文件,然后使用 vimdiff 编辑它们的简单脚本。
- pacfiles-mode — 用于 Emacs 的软件包,用于管理和合并 .pacnew 文件。
- pacdiff-pacman-hook-git — 用于自动运行 pacdiff 的 Pacman 钩子。
参见
- 论坛帖子:处理 .pacnew 文件