Pacman/pacnew 與 pacsave

出自 Arch Linux 中文维基

在使用 pacman 移除一個帶有配置文檔的軟件包時,pacman 通常會將配置文檔複製為一個後綴名為 .pacsave 的備份文檔。

同樣的,當 pacman 升級一個軟件包,而新軟件包含有與與當前配置不同的新配置文件時,pacman 會將新配置寫入 .pacnew 文件。當寫入這些文件時,pacman 會輸出提示信息。

為什麼創建了這樣的文件[編輯 | 編輯原始碼]

當升級某個軟件包(命令為 pacman -Syupacman -Su 或者pacman -U)時,可能會創建一個 .pacnew 文件,以避免覆蓋一個之前被用户修改過的已存在文件。此時,pacman會輸出如下信息:

warning: /etc/pam.d/usermod installed as /etc/pam.d/usermod.pacnew

當卸載某個軟件包(命令為 pacman -R)或升級某個軟件包(該軟件包必須首先被卸載)時,可能會創建一個 .pacsave 文件。當 pacman 數據庫記錄了應當備份該軟件包的某個文件時,pacman 會創建一個 .pacsave 文件。此時,pacman 會輸出如下信息:

warning: /etc/pam.d/usermod saved as /etc/pam.d/usermod.pacsave

這些文件需要用户手動干預,我們推薦您在每次軟件包升級或卸載之後馬上處理它們。如果不處理,不當的配置可能導致軟件功能出問題,甚至完全無法使用。

包備份文件[編輯 | 編輯原始碼]

軟件包的 PKGBUILD 文件指定了升級或卸載軟件包時哪寫文件需要被保存或備份。例如,puslseaudioPKGBUILD 文件包含如下行:

backup=('etc/pulse/client.conf' 'etc/pulse/daemon.conf' 'etc/pulse/default.pa')

要阻止任何軟件包覆蓋一個文件,請閱讀 Pacman#Skip file from being upgraded.

類型説明[編輯 | 編輯原始碼]

.pacnew[編輯 | 編輯原始碼]

對於包升級過程中的每個備份文件,pacman 會交叉校驗三個版本的文件內容生成的 md5sums 值:一個為軟件包最初創建的版本,一個為文件系統中當前的版本,還有一個為新軟件包中的版本。如果軟件包安裝的版本被修改為文件系統中當前的版本,pacman 不知道如何將這些修改合併到新版本的文件中。因此,pacman 以擴展名 .pacnew 保存新版本的文件,修改過的版本保持不變,而不是被覆蓋。

更細一步來説,3路MD5值校驗結果為下述輸出之一:

original = X, current = X, new = X
三個版本的文件具有相同的內容,因此覆蓋不會產生問題。pacman 將用新版本覆蓋當前版本而不通知用户。(儘管文件內容相同,覆蓋操作會更新文件系統中和文件創建,修改和訪問時間有關的信息,也確保了任何文件權限的修改被實施。)
original = X, current = X, new = Y
當前版本文件的內容和原始版本的相同,但與新版本不同。既然用户沒有修改過當前版本文件,且新版本可能包含改進和 bug 修正,pacman 用新版本覆蓋當前版本,而不通知用户。這是 pacman 有能力執行的唯一一個新改動的自動合併。
original = X, current = Y, new = X
原始軟件包和新軟件包都包含版本完全相同的文件,但當前文件系統中的版本是被修改過的。此時 pacman 保留當前版本,忽略新版本,且不通知用户。
original = X, current = Y, new = Y
新版本和當前版本相同。此時 pacman 將用新版本覆蓋當前版本且不通知用户。(儘管文件內容相同,覆蓋操作會更新文件系統中和文件創建,修改和訪問時間有關的信息,也確保了任何文件權限的修改被實施。)
original = X, current = Y, new = Z
三個版本的文件都不相同,所以保留當前版本,以擴展名 .pacnew 創建新版本,且警吿用户創建了新版本。希望用户手動將需要的更改由新版本合併至當前版本。

.pacsave[編輯 | 編輯原始碼]

如果用户修改了 backup 中指定的某個文件,那麼那個文件將被重命名,帶上 .pacsave 擴展名,且在其他軟件包移除之後仍然存在於文件系統中。

注意: 使用命令 pacman -R 中的 -n 選項會移除指定軟件包中的所有文件,因此不會創建 .pacsave 文件。

定位 .pac* 文件[編輯 | 編輯原始碼]

首先需要確定這些文件的位置,才能手動維護這些文件。當升級或卸載大量軟件包時,可能會錯過升級的 *.pac* 的信息。你需要尋找是否產生了 *.pac* 文件:

僅搜索絕大多數全局配置文件所存放的位置:

$ find /etc -regextype posix-extended -regex ".+\.pac(new|save)" 2> /dev/null

或全盤搜索:

$ find / -regextype posix-extended -regex ".+\.pac(new|save)" 2> /dev/null

如果你安裝了 locate,還可以使用它來搜索。首先需要更新索引數據庫:

# updatedb

然後:

$ locate --existing --regex "\.pac(new|save)$"

或者使用pacman日誌來找到它們:

$ egrep "pac(new|save)" /var/log/pacman.log

注意:日誌不會記錄文件系統裏現在有哪些文件,也不會記錄哪些文件已經被移除。

管理 .pac* 文件[編輯 | 編輯原始碼]

pacdiff[編輯 | 編輯原始碼]

Pacman 包含了 pacdiff 工具管理 pacnew/pacsave 文件。這個工具會搜索所有的 pacnewpacsave 文件並詢問要執行的操作。默認使用 vimdiff 工具,可以通過 DIFFPROG=your_editor pacdiff 指定要使用的差異比較工具。參考 List of applications/Utilities#Comparison, diff, merge.

三方工具[編輯 | 編輯原始碼]

下面一些 AUR 三方工具可以自動處理這些文件:

  • dotpac — Basic interactive script with ncurses-based text interface and helpful walkthrough. No merging or auto-merging features.
https://github.com/AladW/dotpac || dotpacAUR
  • etc-updateGentoo's utility, compatible with other distributions including Arch. It provides a simple CLI to view, merge and interactively edit changes. Trivial changes, such as comments, can be merged automatically.
https://wiki.gentoo.org/wiki/Handbook:Parts/Portage/Tools#etc-update || etc-update
  • pacnews-git — A simple script aimed at finding all .pacnew files, then editing them with vimdiff.
https://github.com/pbrisbin/scripts/blob/master/pacnews || pacnews-gitAUR
  • pacfiles-mode — A package for Emacs to manage and merge .pacnew files.
https://github.com/UndeadKernel/pacfiles-mode || available in melpa

參閱[編輯 | 編輯原始碼]