由于 lunar 上的 python3,apt-get 无法正常工作

由于 lunar 上的 python3,apt-get 无法正常工作

总结一下:如果 apt-get 检测到错误(例如,找不到源列表中的 repo),它就会崩溃。

导致该问题的原因在于 pythonsqlite3共享对象具有未定义的符号 ( sqlite3_deserialize)。可以从 中重现此问题python3 -c 'import sqlite3'

不幸的是,由于 aptitude 依赖于 python3,任何故障都可能导致 pythonCommandNotFound功能尝试import sqlite3崩溃(相关日志如下)。

在撰写本文时,似乎唯一可用的 python 包是 3.11.2-1,所以我无法升级/降级。

有问题的共享对象是/usr/lib/python3.11/lib-dynload/_sqlite3.cpython-311-x86_64-linux-gnu.so

apt-file 表明该文件是libpython3.11-stdlib软件包的一部分。

我在网上没有看到任何关于此事的结论,所以也许我做错了什么,但我想象不出是什么。有没有人运行过 lunar 来验证这一点?

谢谢

sudo apt-get update
Hit:1 http://gb.archive.ubuntu.com/ubuntu lunar InRelease
Hit:2 http://gb.archive.ubuntu.com/ubuntu lunar-updates InRelease
Hit:3 http://gb.archive.ubuntu.com/ubuntu lunar-backports InRelease
Hit:4 http://gb.archive.ubuntu.com/ubuntu lunar-security InRelease
Traceback (most recent call last):
  File "/usr/lib/cnf-update-db", line 9, in <module>
    from CommandNotFound.db.creator import DbCreator
  File "/usr/lib/python3/dist-packages/CommandNotFound/db/creator.py", line 7, in <module>
    import sqlite3
  File "/usr/lib/python3.11/sqlite3/__init__.py", line 57, in <module>
    from sqlite3.dbapi2 import *
  File "/usr/lib/python3.11/sqlite3/dbapi2.py", line 27, in <module>
    from _sqlite3 import *
ImportError: /usr/lib/python3.11/lib-dynload/_sqlite3.cpython-311-x86_64-linux-gnu.so: undefined symbol: sqlite3_deserialize
Reading package lists... Done
E: Problem executing scripts APT::Update::Post-Invoke-Success 'if /usr/bin/test -w /var/lib/command-not-found/ -a -e /usr/lib/cnf-update-db; then /usr/lib/cnf-update-db > /dev/null; fi'
E: Sub-process returned an error code

答案1

本质上,这个问题是操作员错误。感谢steeldriver 向我指出了原因。以下是为遇到此问题的其他人员提供的解释:

正如steeldriver指出的那样,python3没有找到正确的共享对象,而是从我无意中添加的另一个安装中加载了一个共享对象。

在这种情况下,错误消息指向缺少的符号:sqlite3_deserialize共享对象所需的(函数)/usr/lib/python3.11/lib-dynload/_sqlite3.cpython-311-x86_64-linux-gnu.so

错误不在于该共享对象,而在于它加载的共享对象都不包含该符号。

使用nm命令我们可以看到库中存在的所有符号以及它需要的符号。需要的符号标记为U

nm -gD /usr/lib/python3.11/lib-dynload/_sqlite3.cpython-311-x86_64-linux-gnu.so | less 如果我们搜索反序列化,我们可以看到U sqlite3_deserialize它需要这个符号。

使用ldd我们可以命令 linux 加载器实际加载该库及其所有依赖库并找出实际正在加载的库: ldd /usr/lib/python3.11/lib-dynload/_sqlite3.cpython-311-x86_64-linux-gnu.so

正如steeldriver指出的那样,它加载的/usr/local/lib/libsqlite3.so.0版本不正确。nm在错误的文件上运行显示该文件中不存在所需的符号,这就是问题的原因。

lunar 中正确的 sqlite3 包是libsqlite3-0(这并不明显)。如果不确定,我们可以尝试从apt-cache search libsqlite3或类似的东西中找到正确的包,然后筛选结果。

我们可以通过先安装然后运行来查看此包安装了哪些文件dpkg -L libsqlite3-0。在返回的文件列表中,我们可以看到/usr/lib/x86_64-linux-gnu/libsqlite3.so.0应该加载哪个文件。

那么我们如何确保 Linux 加载程序选择正确的共享对象版本?理想情况下,我们应该只有一个版本的 sqlite3,因此最好的解决方案是删除非标准版本。另一个潜在的解决方案是使用环境变量将加载程序指向正确的路径LD_LIBRARY_PATH。类似这样的方法可能会有效export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH(添加到~/.bashrc持久性)。请注意,将其放在前面会导致首先搜索该目录。如果问题仍然存在,只需ldd再次运行以验证正在加载的内容。

相关内容