pacman/恢复本地数据库
pacman 需要恢复本地数据库的迹象
pacman -Q
完全没有输出,并且pacman -Syu
错误地报告系统是最新的。- 当尝试使用
pacman -S package
安装软件包时,它输出了一个已满足依赖项的列表。
很可能,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
,然后重试之前的命令。检查是否缺少一些重要的基础软件包,并将它们添加到列表中
$ 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