我们收到了很多关于人们乱改 Python 版本并破坏系统的问题,最明显的是 apt 无法正常运行。我知道许多 Ubuntu 软件包需要特定版本的 Python才能正常运作。
我的问题是:是什么导致较新/不同的 Python 版本与 apt 不兼容?这些软件包是否依赖于仅存在于某些版本中的语言功能,或者 apt 依赖于哪些特定于版本的 Python 功能,导致它只能与一个特定的 Python 版本一起使用?
答案1
是的,它通常是仅存在于某个 Python 版本中的特定语言功能。
根据问题的不同,当 apt 或更可能是 dpkg 等应用程序使用新版本中不存在的错误语法调用某些内容时,您经常会收到错误。
然而apt 本身不依赖于 pythondpkg 也是如此 — 但依赖于 python 的包通常具有调用 python 或 python 脚本的安装前和安装后脚本。
例如,如果您下载了 的 deb 文件software-properties-gtk
,提取该文件,然后提取该control.tar.xz
文件,您将看到一个prerm
脚本。
该脚本是一个 sh 脚本,但您可以看到它也调用了 python:
#!/bin/sh
set -e
# Automatically added by dh_python3:
if which py3clean >/dev/null 2>&1; then
py3clean -p software-properties-gtk
else
dpkg -L software-properties-gtk | perl -ne 's,/([^/]*)\.py$,/__pycache__/\1.*, or next; unlink $_ or die $! foreach glob($_)'
find /usr/lib/python3/dist-packages/ -type d -name __pycache__ -empty -print0 | xargs --null --no-run-if-empty rmdir
fi
# End automatically added section
所以py3clean
是其一部分python3-minimal
python3
并且该脚本在文件第一行的shebang中调用,如以下命令所示:
which py3clean
并且应该显示/usr/bin/py3clean
如下:
head /usr/bin/py3clean
输出:
#! /usr/bin/python3
# vim: et ts=4 sw=4
# Copyright © 2010-2012 Piotr Ożarowski <[email protected]>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
/usr/bin/python3
这很重要,因为通过以下命令可以看到实际的文件并不存在:
file /usr/bin/python3
在 20.04 上,这告诉我这/usr/bin/python3
是 python3.8 的符号链接,并which python3.8
显示此文件是/usr/bin/python3.8
。此外,file /usr/bin/python3.8
确认这是用于 python3 的实际 Python 可执行文件。
因此,该software-properties-gtk
包期望,如果安装了 python3,则安装的 python3 版本是 python3.8。
该py3clean
脚本可能适用于或不适用于不同的 Python 版本,但 Python 经常会有足够的变化,以至于脚本中的某个地方可能至少有一个变化会导致某种类型的错误。
即使不是针对这种特殊情况,你也能明白。
我想总结一下,这实际上不是 apt 的问题,而是 python 的问题,因为 python 脚本通常使用通用的 shebang,当 shebang 指定/usr/bin/python
或/usr/bin/python3
甚至/usr/bin/env python
或/usr/bin/env python3
由于这些都没有指向实际文件时,它会期望特定版本的 python,它们都指向指向系统上安装的默认 python 版本的符号链接。
由于大多数软件包都是针对特定版本的 Ubuntu 发布的,因此它们都期望 Python 的默认版本相同。否则,每个软件包都会依赖于任意不同的 Python 版本,我们最终可能会在同一系统上安装 3 个或更多版本的 Python,只是为了满足依赖关系。
通常,如果您想要或需要安装不同版本的 Python,那是因为您有特殊原因。没有什么可以阻止您出于该原因使用不同版本的 Python,只要您不干扰其他软件在调用或时使用的默认 Pythonpython
版本python3
。
因此,如果您确实安装了替代版本,那么您将无法方便地通过python
或将该替代版本调用python3
为默认版本 - 您将需要通过调用来专门指定版本python3.9
,例如,当您使用它时。
我想我应该为阅读此答案的其他人添加免责声明。如果您想在系统上安装不同版本的 Python,您应该四处询问以找到正确的方法。一个系统上可以有多个版本的 Python,但为了避免出现问题,您不得以任何方式卸载、更改或改变 Python 的默认版本。但我认为更详细地讨论不属于这个问题的范围。