Pacman/Restore local database

出自 Arch Linux 中文维基

如果遇到下面的問題,很可能需要恢復pacman本地數據庫:

  • pacman -Q什麼都不輸出,pacman -Syu錯誤地報吿系統已為最新。
  • 使用pacman -S安裝軟件包時,很多已經安裝過的依賴提示未安裝。

pacman儲存本地軟件包的數據庫/var/lib/pacman/local很可能已經損壞甚至丟失。這是很嚴重的問題,請按照如下步驟修復。

首先,確認pacman的日誌文件還在:

$ ls /var/log/pacman.log

如果日誌丟失了,那就不能使用本方法修復,可以嘗試使用Xyne的軟件包檢測腳本重建數據庫。要是還行不通,很遺憾,最後的路就是重裝系統。

日誌過濾腳本[編輯 | 編輯原始碼]

創建一個awk腳本文件,內容如下基於[1]

log2pkglist.awk
#!/bin/awk -f

i = 3 {}

$3 ~ /^\[[^]]+\]$/ {
  i = 4
}

$i ~ /^(installed|upgraded)$/ {
  pkg[$(i+1)] = 1
  next
} 

$i == "removed" {
  pkg[$(i+1)] = 0
} 

END {
  for (i in pkg) if (pkg[i]) print i
}

打上可執行標誌:

$ chmod +x log2pkglist.awk

生成軟件包列表[編輯 | 編輯原始碼]

運行該腳本,輸出到一個文本文件中:

$ ./log2pkglist.awk /var/log/pacman.log > pkglist.orig

(可選)手動檢查pkglist.orig,刪除所有不需要重新安裝的軟件包,例如:自己從ABS安裝的軟件包。

過濾掉無法從軟件倉庫中安裝的軟件包:

$ { cat pkglist.orig; pacman -Slq; } | sort | uniq -d > pkglist
注意: If this fails with failed to initialise alpm library, then check if /var/lib/pacman/local/ALPM_DB_VERSION exists - if not, then run pacman-db-upgrade as root followed by pacman -Sy and then retry the previous command.

檢查base軟件包組中的軟件包是否缺失,並加入列表:

$ comm -23 <(pacman -Sgq base) pkglist.orig >> pkglist

pkglist列表內容完備後,繼續下一步,利用這個列表恢復數據庫。

恢復數據庫[編輯 | 編輯原始碼]

建立臨時的緩存、數據庫以及根目錄:

tmp=~/tmp
mkdir -p "${tmp}"

pushd "${tmp}"
dbpath=$(readlink -f ./dbpath)
root=$(readlink -f ./root)
cache=$(readlink -f ./cache)
log=/dev/null
mkdir -p "${dbpath}" "${cache}" "${root}"
popd

recovery-pacman() {
     sudo pacman "$@"  \
     --log /dev/null   \
     --noscriptlet     \
     --dbonly          \
     --force           \
     --nodeps          \
     --needed
 }

同步臨時目錄中的數據庫:

$ recovery-pacman -Sy

或者複製系統的數據庫:

$ cp -r /var/lib/pacman/sync "${dbpath}"

(可選)要避免下載和處理當前系統本地數據庫中存在的軟件包,複製本地數據庫到臨時目錄:

$ cp -r /var/lib/pacman/local "${dbpath}"

從上一步獲取的pkglist生成臨時本地數據庫:

$ recovery-pacman -S --nodeps --needed $(< pkglist)
注意: 由於--noscriptlet選項,fakeroot生成的文件不會被真正安裝到系統中。

生成數據庫後,複製到真正的系統中:

# cp -r "${dbpath}"/local /var/lib/pacman

最後,更新本地數據庫,將不受其他軟件包依賴的軟件包標記為手動安裝,剩下的標記為依賴安裝:

# pacman -D --asdeps $(pacman -Qq)
# pacman -D --asexplicit $(pacman -Qtq)