近日,Ubuntu 16.04.x LTS可通过执行do-release-upgrade
升级到18.04.1 LTS,故将一台VPS升级。
升级过程大体顺利,除了一些包的配置文件需要更新——我将diff
输出的对比内容截图后保留(VNC Console中无法复制文本),并在系统更新完毕后将必要的行恢复到对应文件即可。
但升级后,我发现系统使用apt upgrade
时无法升级g++和build-essential两个包(后者依赖前者,因而也无法升级)。
我首先尝试了网路上的方法——卸载重装,却发现卸载后无法重新安装,安装g++时出现了更多依赖错误,试图通过apt install
安装每个有依赖错误的包,最终发现是gcc-8-base的版本问题。
此外,还有以下包也存在版本问题:
libatomic1
libgcc1
libgomp1
libitm1
liblsan0
libstdc++6
libtsan0
apt建议执行apt --fix-broken install
,然而这完全不能解决问题。
gcc-8-base的版本号中存在8.1.0-5ubuntu1~16.04
字样。检索后,发现是由ppa:ubuntu-toolchain-r/test提供的版本。回想起在这VPS运行Ubuntu 16.04.5期间,曾为使用新版本的gcc而添加了此第三方源。这个源提供的gcc-8-base没有被直接升级到Ubuntu 18.04.1所提供的版本,进而导致这些问题。
而gcc-8-base似乎是很多其他程序的依赖,尝试在apt中卸载它,会提示很多包也会被卸载,不仅包括自行安装的许多软件,甚至还包含libc6、dpkg和apt等,apt还要求输入Yes, do as I say!
才能继续——无疑,这样做会损坏系统。
尝试使用apt install --reinstall gcc-8-base
来重新安装,也不可行,出现'找不到对应版本'的提示——这似乎是因为第三方源提供的版本被apt认为版本号比官方源提供的更高。
而使用apt-cache show gcc-8-base
检索所有可用版本后,发现官方源所提供的版本号为8-20180414-1ubuntu2
,试图用apt install --reinstall --allow-downgrade gcc-8-base=8-20180414-1ubuntu2
来重新安装指定版本,却因为是降级操作,必须卸载再安装,遇到了相同的问题(会导致关键包被一并卸载,系统损坏)。
由此一来,便无法只通过apt来完成对gcc-8-base降级。
印象中使用dpkg -i
安装一个已安装的deb包的历史版本,可以将其覆盖并完成降级。于是便做了如下尝试:
- 通过
apt-cache show 包名
查找每个有问题的包的官方源版本号 - 通过
apt download 包名=版本号
将deb包下载至一个目录 - 在此目录中通过
dpkg -i *.deb
来完成覆盖降级
这样做成功了。但要先降级gcc-8-base,再降级其它版本有问题的包,否则还是会出现依赖问题。
通过apt list --installed| less
检索gcc-8-base版本,得到如下结果
gcc-8-base/bionic,now 8-20180414-1ubuntu2 amd64 [installed]
说明降级成功。再次尝试安装g++和build-essential,没有出现问题。