如果遇到下面的問題,很可能需要恢復 pacman 本地資料庫:
-
pacman -Q
什麼都不輸出,pacman -Syu
錯誤地報告系統已為最新。 - 使用
pacman -S
安裝軟體包時,很多已經安裝過的依賴提示未安裝。
pacman 儲存本地軟體包的資料庫 /var/lib/pacman/local
很可能已經損壞甚至丟失。這是很嚴重的問題,請按照如下步驟修復。
首先,確認 pacman 的日誌文件還在:
$ ls /var/log/pacman.log
如果日誌丟失了,那就不能使用本方法修復,可以嘗試使用Xyne的軟體包檢測腳本重建資料庫。要是還行不通,很遺憾,最後的路就是重裝系統。
生成軟體包恢復清單
安裝 pacman-contrib包 以獲取 paclog-pkglist。
創建日誌過濾腳本並使其可執行:
pacrecover
#!/bin/bash -e # load configuration settings from the makepkg configuration file . /etc/makepkg.conf # determine the cache directory from pacman configuration, defaulting to /var/cache/pacman/pkg, remove prefix with sed PKGCACHE=$( (grep -m 1 '^CacheDir' /etc/pacman.conf || echo 'CacheDir = /var/cache/pacman/pkg') | sed 's/CacheDir = //') # define directories to search for package files pkgdirs=("$@" "$PKGDEST" "$PKGCACHE") # read package name and version from input and construct a search pattern for package files while read -r -a parampart; do # loop through each directory to search for matching package files for pkgdir in "${pkgdirs[@]}"; do # check each file matching the pattern in the current directory for i in "$pkgdir"/"${parampart[0]}"-"${parampart[1]}"-*.pkg.tar.{xz,zst} ; do # if a file exists, print its path and stop checking further [ -f "${i}" ] && { echo "${i}" ; break; }; done # If no file is found, output the package name to stderr done || echo "${parampart[0]}" 1>&2 done
運行腳本(可選擇將帶有包的目錄作為參數):
$ paclog-pkglist /var/log/pacman.log | ./pacrecover >files.list 2>pkglist.orig
這樣做會創建兩個文件:files.list
存儲著依然在設備上的軟體包的包文件;pkglist.orig
存儲著需要下載的包。接下來的操作可能會導致設備上的舊版本包的部分文件與新版不匹配,需要手動干預。
過濾掉第二個列表中無法用軟體倉庫安裝的包:
$ { cat pkglist.orig; pacman -Slq; } | sort | uniq -d > pkglist
failed to initialise alpm library
,請檢查/var/lib/pacman/local/ALPM_DB_VERSION
是否存在。若不存在,請以 root 執行pacman-db-upgrade
,然後執行 pacman -Sy
,接下來重試之前的命令。檢查是否缺失一些重要的 base 軟體包並將它們加入列表:
$ comm -23 <({ echo base ; expac -l '\n' '%E' base; } | sort) pkglist.orig >> pkglist
如果兩個列表的內容均就緒,無甚缺漏,就請繼續下一步,它們將被用於恢復 pacman 的已安裝軟體包資料庫 /var/lib/pacman/local/
。
開始恢復
為恢復工作定義一個 bash 函數。
recovery-pacman() { pacman "$@" \ --log /dev/null \ --noscriptlet \ --dbonly \ --overwrite "*" \ --nodeps \ --needed }
--log /dev/null
參數可以避免污染 pacman 日誌;--needed
參數可以跳過資料庫中已存在的包以節省時間;--nodeps
參數允許安裝已緩存的包,即使已安裝的包依賴於更新版本。其餘選項用於使 pacman 在進行操作時不讀寫文件系統。
同步資料庫:
# pacman -Sy
從 files.list
安裝本地可用的包以開始生成資料庫:
# recovery-pacman -U $(< files.list)
從 pkglist
安裝其餘包:
# recovery-pacman -S $(< pkglist)
更新本地資料庫以將不被其它包依賴的包標記為明確按照並將其它包標記為依賴。您將來在移除軟體包時需要格外小心,但是原始資料庫已丟失,這已經是我們所能做的最好的。
# pacman -D --asdeps $(pacman -Qq) # pacman -D --asexplicit $(pacman -Qtq)
可選檢查安裝的軟體包是否損壞:
# pacman -Qk
可選參閱 Pacman/提示和技巧#查找不屬於任何軟體包的文件。
更新所有軟體包:
# pacman -Su