强行魔改最 (bìng) 为 (bù) 致命


# 前情提要

今天在探索 PYNQ on Z7020,安装完镜像执行 sudo apt update && sudo apt upgrade 时,
碰到了这个问题。

硬件是正点原子启明星 V2,系统镜像为正点原子提供的 pynq on ubuntu18.04.

# 日志

(说起来可以做一个代码折叠功能?

Unpacking vim-tiny (2:8.0.1453-1ubuntu1.8) over (2:8.0.1453-1ubuntu1) ...
dpkg: error processing archive /var/cache/apt/archives/vim-tiny_2%3a8.0.1453-1ubuntu1.8_armhf.deb (--unpack):
 trying to overwrite '/usr/share/vim/vim80/doc/help.txt', which is also in package vim-runtime 2:8.0.1453-1ubuntu1
dpkg: considering deconfiguration of vim-tiny, which would be broken by installation of vim-runtime ...
dpkg: yes, will deconfigure vim-tiny (broken by vim-runtime)
Preparing to unpack .../vim-runtime_2%3a8.0.1453-1ubuntu1.8_all.deb ...
De-configuring vim-tiny (2:8.0.1453-1ubuntu1) ...
Unpacking vim-runtime (2:8.0.1453-1ubuntu1.8) over (2:8.0.1453-1ubuntu1) ...
dpkg: error processing archive /var/cache/apt/archives/vim-runtime_2%3a8.0.1453-1ubuntu1.8_all.deb (--unpack):
 trying to overwrite '/usr/share/vim/vim80/doc/help.txt', which is also in package vim-tiny 2:8.0.1453-1ubuntu1
dpkg-deb: error: paste subprocess was killed by signal (Broken pipe)
Errors were encountered while processing:
 /var/cache/apt/archives/vim-tiny_2%3a8.0.1453-1ubuntu1.8_armhf.deb
 /var/cache/apt/archives/vim-runtime_2%3a8.0.1453-1ubuntu1.8_all.deb
E: Sub-process /usr/bin/dpkg returned an error code (1)

# 定位及分析

可以看到日志里说,两个 deb 都修改了 /usr/share/vim/vim80/doc/help.txt 这个文件,所以
自然而然地,我们就可以想到删除一个 deb 包里的这一文件。

其实更安全一点的解决办法是先将两个包里的这一文件都提取出来做 diff,不过从名字看起来,
这个文件是一个用户文档,所以直接删除影响应该不大。

# 解决方案

可以看到我在修复 deb 时,apt 始终是挂起状态。这里主要是防止如下情况发生:apt 对包可能进行哈希验证(仅猜测),修改后验证失败触发重新下载。

部分命令参考 [1]。

  1. sudo apt install --fix-broken 打开 apt 界面,不确认继续安装
  2. cd /var/cache/apt/archives/ 新开一个终端,进入包缓存目录
  3. sudo mkdir extracted 创建一个目录用于存放解压后文件
  4. sudo dpkg -X vim-tiny_2%3a8.0.1453-1ubuntu1.8_armhf.deb extracted/ 解压其中一个包
  5. sudo dpkg -e vim-tiny_2%3a8.0.1453-1ubuntu1.8_armhf.deb extracted/DEBIAN/ 解压包的控制信息
  6. sudo rm -rf extracted/usr/share/vim/vim80/doc 删除冲突文件(偷懒直接删除了整个文件夹
  7. sudo mkdir build && dpkg-deb -b extracted/ build/ 重新打包
  8. cp build/vim-tiny_8.0.1453-1ubuntu1.8_armhf.deb vim-tiny_2%3a8.0.1453-1ubuntu1.8_armhf.deb 将打包好的 deb 文件替换掉原本缓存的 deb(注意名称!)
  9. 回到 apt 的窗口,确认继续安装
  10. 问题解决!

# 后记

感觉这种 hack 有点不安全.. 不过很爽 /doge

# 参考

[1] 对一个 deb 包的解压、修改、重新打包全过程方法