1. 为什么在Ubuntu 24.04上装Python2会这么“费劲”?
如果你最近刚把开发环境升级到Ubuntu 24.04 LTS,然后想装个Python2来跑一些老项目或者维护遗留脚本,大概率会一头撞上南墙。你会发现,用你熟悉的sudo apt install python2或者sudo apt install python命令,系统会直接告诉你“找不到这个包”。这可不是网络问题,也不是你敲错了命令,而是Ubuntu官方在24.04这个版本上,做了一个相当“决绝”的决定:彻底从官方软件源中移除了Python 2.7的安装包。
这背后其实是一个持续了多年的“告别”故事。Python 2在2020年1月1日就已经正式结束了官方支持。主流Linux发行版,包括Ubuntu,都遵循着上游的决策,逐步将其从默认安装和软件仓库中剔除。在Ubuntu 22.04 LTS时,虽然默认不预装,但你还能从universe仓库里找到python2和python2.7包。但到了24.04,这个最后的“后门”也被关上了。官方软件源里,与Python 2.7直接相关的包基本被清理干净了。
所以,当你遇到安装失败时,根本原因不是你的操作有问题,而是“货源”断了。系统自带的APT工具,它的工作就是去配置好的软件仓库列表(主要是archive.ubuntu.com等官方源)里查找并下载包。现在仓库里没这个货了,它自然就报“无法定位软件包”(E: Unable to locate package python2)。这和你去一家已经停售某种商品的超市,非要买这个东西是一个道理。
那么,我们是不是就束手无策了?当然不是。虽然官方“大路”走不通了,但我们还有几条“小路”可以走通。这些方法各有优劣,有的方便但可能不够“干净”,有的稳定但需要多费些功夫。接下来,我们就来逐一拆解这些方法,并告诉你每种方法背后可能遇到的“坑”以及如何避开它们。我们的目标很明确:在Ubuntu 24.04上,安全、稳定地运行起Python 2.7环境,让你那些老代码重新转起来。
2. 方案一:使用第三方PPA源——最快捷的“借道”方案
对于习惯了APT包管理器的用户来说,最顺手的解决方案就是找一个还提供Python 2.7包的第三方软件源。PPA(Personal Package Archive)是Ubuntu独有的一个功能,允许开发者和团队为自己开发的软件建立独立的APT仓库。有一些PPA专门为了兼容性目的,维护着一些已从官方源移除的旧版软件。
2.1 寻找并添加可靠的PPA
经过社区验证,一个比较常用且相对可靠的PPA是deadsnakes/ppa。这个团队以维护多个Python版本(包括旧版本)的构建而闻名。但请注意,使用任何第三方源都有潜在风险,你需要信任该源的维护者。
添加PPA和安装的命令序列如下:
# 1. 更新本地软件包列表,确保基础信息是最新的 sudo apt update # 2. 安装software-properties-common包,它提供了管理PPA所需的`add-apt-repository`命令 # 如果你的系统已经装了这个包,可以跳过。但新装系统很可能没有。 sudo apt install software-properties-common -y # 3. 添加deadsnakes PPA源 sudo add-apt-repository ppa:deadsnakes/ppa -y # 4. 再次更新软件包列表,这次会拉取新添加的PPA中的包信息 sudo apt update # 5. 安装Python 2.7 sudo apt install python2.7 -y执行完上述命令后,你应该可以通过python2.7 --version来验证安装是否成功。
2.2 此方案的潜在风险与注意事项
这个方法虽然简单,但你必须清楚以下几点:
- 系统兼容性与依赖冲突风险:PPA中的包是为特定Ubuntu版本构建的。
deadsnakes/ppa的维护者会为新的Ubuntu版本(如24.04)重新构建Python 2.7。然而,Python 2.7本身依赖一系列系统库(如libc、openssl等)。如果PPA中的包是链接了与Ubuntu 24.04基础系统不兼容的库版本,可能会导致运行时错误,甚至影响系统稳定性。虽然deadsnakes口碑较好,但风险依然存在。 - 与系统Python 3的隔离问题:安装后,
python2.7这个命令是可用的,但python2或python命令默认可能仍然指向Python 3。为了避免混淆和误操作,强烈不建议你使用update-alternatives或其他方法将系统级的python命令指向Python 2。这可能会破坏许多依赖Python 3的系统工具(如Ubuntu的软件中心、apt等)。正确的做法是,在需要运行Python 2脚本时,显式地使用python2.7命令,或者在脚本的开头使用#!/usr/bin/env python2.7这样的shebang。 - 未来维护的不确定性:PPA是由个人或小团队维护的,其持续性和稳定性无法像官方源那样得到保证。也许未来某一天,这个PPA停止了对Ubuntu 24.04的支持,那么你将无法通过它获得安全更新(尽管Python 2本身已无官方安全更新)。
注意:在添加任何PPA之前,建议先快速浏览一下其Launchpad页面,看看最近是否有更新,以及其他用户的反馈。对于生产环境,此方案需谨慎评估。
3. 方案二:手动编译安装——最彻底、最可控的“自力更生”
如果你对系统洁癖有要求,或者担心第三方包带来不可预见的依赖问题,那么从源代码手动编译安装是最稳妥、最干净的方法。这相当于你自己从原始材料开始,建造一个独立的Python 2.7环境,完全不影响系统原有的任何配置。
3.1 编译前的准备工作:安装构建工具和依赖库
编译软件需要一套“工具链”和该软件所依赖的库。我们需要先安装它们。
# 更新软件列表并安装编译必需的工具 sudo apt update sudo apt install build-essential -y # 安装Python编译过程中需要的特定开发库 # 这些库的头文件和链接文件是成功编译的关键,缺少它们会导致configure或make失败。 # 主要包含:zlib(压缩)、libssl(SSL/TLS)、libffi(外部函数接口)、libsqlite3(数据库)、libreadline(命令行编辑)等。 sudo apt install zlib1g-dev libssl-dev libffi-dev libsqlite3-dev libreadline-dev libncursesw5-dev libgdbm-dev libbz2-dev -ybuild-essential是一个元数据包,它包含了gcc、g++、make等最核心的编译工具。后面安装的那些*-dev包,则是Python源代码在编译过程中需要链接的特定库的开发文件。没有它们,编译出的Python可能会缺少某些模块(比如无法导入ssl模块,导致pip无法通过HTTPS下载包)。
3.2 下载源码、编译与安装
我们选择Python 2.7的最终版本2.7.18。
# 1. 创建一个临时工作目录并进入 mkdir -p ~/python2_build && cd ~/python2_build # 2. 从Python官网下载2.7.18的源代码压缩包 wget https://www.python.org/ftp/python/2.7.18/Python-2.7.18.tgz # 3. 解压源代码 tar -xzf Python-2.7.18.tgz cd Python-2.7.18 # 4. 配置编译选项 # --prefix=/usr/local/python2.7:指定安装目录。将其安装到/usr/local下,与系统自带的/usr/bin/python3隔离。 # --enable-optimizations:启用一些优化,可能会让Python运行稍快一点(此选项会大大延长编译时间,可选)。 ./configure --prefix=/usr/local/python2.7 # 5. 开始编译。`-j` 参数指定使用多少个CPU核心并行编译,可以加快速度。`nproc`命令会输出你CPU的核心数。 make -j$(nproc) # 6. 安装到第4步指定的目录 sudo make install编译过程可能会花费几分钟到十几分钟,取决于你的机器性能。完成后,Python 2.7的可执行文件就位于/usr/local/python2.7/bin/python2.7。
3.3 创建软链接与环境变量配置
为了方便使用,我们通常希望能在终端里直接输入python2.7就能调用它。
# 为python2.7创建全局软链接(可选,但推荐) sudo ln -sf /usr/local/python2.7/bin/python2.7 /usr/local/bin/python2.7现在,你可以在任何终端中直接使用python2.7命令了。如果你希望将/usr/local/python2.7/bin添加到你的用户PATH环境变量中,可以编辑~/.bashrc文件(如果你用的是bash):
echo 'export PATH="/usr/local/python2.7/bin:$PATH"' >> ~/.bashrc source ~/.bashrc这样做之后,你甚至可以直接使用pip2(如果安装了的话)等命令。
3.4 手动安装方案的优缺点分析
优点:
- 完全独立:安装到
/usr/local,与系统包管理器(APT)管理的/usr目录完全分开,零干扰。卸载时直接删除/usr/local/python2.7目录和创建的软链接即可,非常干净。 - 版本可控:你可以选择编译任何一个你需要的Python 2.7.x版本,甚至可以应用一些特定的补丁。
- 学习价值:通过这个过程,你能更深入地理解软件从源码到可执行文件的构建流程。
缺点:
- 过程繁琐:步骤较多,需要手动处理依赖和编译。
- 自行维护:这意味着你需要自己负责这个Python环境的所有事情,包括后续如果需要安装Python包,需要手动管理
pip和setuptools。 - 无自动更新:这当然不是问题,因为Python 2本身已停止更新。但意味着任何安全漏洞都需要你自己关注(虽然不再有官方补丁)。
4. 方案三:使用虚拟环境或容器——最现代、最隔离的“沙盒”方案
如果你只是临时需要运行某个特定的、依赖Python 2的老项目,那么将整个Python 2环境封装起来,与主机系统彻底隔离,是最优雅和安全的做法。这里有两个主流方向:使用virtualenv虚拟环境,或者使用Docker容器。
4.1 使用Virtualenv创建独立环境(需先有Python2解释器)
virtualenv是一个创建独立Python环境的工具。但请注意,它需要一个已有的Python解释器作为基础。因此,你需要先通过上述**方案一(PPA)或方案二(编译)**在系统上安装一个Python 2.7解释器。
假设你已经通过PPA安装了python2.7,那么接下来:
# 1. 安装virtualenv工具(使用Python 3的pip3安装) sudo apt install python3-pip -y pip3 install virtualenv # 2. 为你项目创建一个新的虚拟环境目录,并指定使用python2.7作为解释器 virtualenv --python=python2.7 ~/my_py2_project_env # 3. 激活虚拟环境 source ~/my_py2_project_env/bin/activate # 激活后,你的命令行提示符通常会变化,前面会有环境名(如(my_py2_project_env)) # 此时,which python 和 which pip 都会指向虚拟环境目录下的版本 # 你可以在这个环境里用pip安装任何只针对此项目的包,不会影响系统级或其他项目的包。 # 4. 使用完毕后,退出虚拟环境 deactivate这种方法的好处是,你可以在同一台机器上为不同的项目创建多个互不干扰的Python 2环境,每个环境都有自己的包集合。缺点是,你仍然需要在主机系统上安装一个“基础”的Python 2.7。
4.2 使用Docker容器——终极隔离方案
Docker是当前解决环境依赖问题的最强大工具。它直接打包一个包含完整文件系统的轻量级“容器”,里面可以是一个完整的、旧版本的操作系统和Python 2.7环境,与你的Ubuntu 24.04主机完全隔离。
步骤:
安装Docker:如果你的系统还没有Docker,需要先安装。
# 安装Docker官方提供的便捷脚本(推荐用于桌面环境快速安装) curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh # 将当前用户加入docker组,以便无需sudo运行docker命令 sudo usermod -aG docker $USER # 注销并重新登录,使组权限生效安装后,可以运行
docker --version验证。拉取Python 2.7官方镜像:Docker Hub上有官方维护的
python:2.7-slim镜像,非常轻量。docker pull python:2.7-slim运行一个交互式容器:这相当于你进入了一个全新的、只包含Python 2.7的小系统。
docker run -it --rm --name my_py2_container -v $(pwd):/workspace python:2.7-slim bash-it:交互式终端。--rm:容器退出后自动删除,避免积累无用容器。--name:给容器起个名字。-v $(pwd):/workspace:将主机当前目录挂载到容器的/workspace目录。这样你就可以在容器内访问和修改主机上的项目代码了。bash:启动容器后运行的命令,这里我们启动一个shell。
现在,你就在容器内部了。你会发现
python --version就是2.7.x,pip也是可用的。你可以在/workspace目录下操作你的项目文件,安装依赖(pip install -r requirements.txt),运行脚本,所有操作都局限在这个容器里。输入
exit退出容器,由于使用了--rm参数,这个临时容器会被自动删除,不留任何痕迹。
Docker方案的优势:
- 绝对干净:主机系统上除了Docker引擎,不需要安装任何Python 2相关的东西。
- 环境一致性:镜像内容固定,在任何地方运行结果都一样,完美解决了“在我机器上好好的”问题。
- 易于分发:你可以将你的项目代码和Dockerfile(定义如何构建镜像的脚本)一起打包,其他人一键就能复现完全相同的环境。
对于长期维护的、复杂的遗留Python 2项目,我强烈推荐使用Docker。它为你的现代操作系统和古老运行环境之间,筑起了一道完美的防火墙。
5. 安装后的关键步骤与常见问题排雷
无论你通过哪种方式成功安装了Python 2.7,接下来都会面临两个最实际的问题:如何安装第三方包(pip)以及如何与系统自带的Python 3和平共处。
5.1 为Python 2.7安装和配置pip
Python 2.7.9 及以后版本自带了pip,但如果你安装的版本较旧,或者通过编译安装,可能需要手动安装。最可靠的方法是使用get-pip.py脚本。
# 首先确保你的python2.7命令可用 # 下载get-pip.py安装脚本 curl https://bootstrap.pypa.io/pip/2.7/get-pip.py -o get-pip.py # 使用python2.7运行这个脚本进行安装 # 如果你将python2.7安装到了非标准路径,请使用完整路径,例如 /usr/local/python2.7/bin/python2.7 sudo python2.7 get-pip.py安装完成后,pip2或pip2.7命令应该就可用了。你可以用pip2.7 --version来验证。
重要提示:永远、永远不要使用
sudo pip install ...(不加版本号)来为Python 2安装包,因为这极有可能调用的是系统Python 3的pip,会把包安装到Python 3的目录下,造成混乱。始终使用pip2.7 install --user [package-name](--user选项将包安装到用户目录,不需要sudo)或者在你激活的虚拟环境内使用pip install。
5.2 处理与Python 3的共存与命令别名
在终端里,python这个命令到底指向谁?在Ubuntu 24.04上,默认情况下,python命令很可能不存在,或者通过python-is-python3这个包被链接到python3。这是一个好的设计,强制你明确指定版本。
检查现状:
ls -l /usr/bin/python* which python which python3最佳实践:
- 不要修改系统默认的
python命令。保持它为Python 3或不存在。 - 在脚本中,始终使用明确的版本号作为shebang:
- Python 2脚本:
#!/usr/bin/env python2.7 - Python 3脚本:
#!/usr/bin/env python3
- Python 2脚本:
- 在命令行中,显式使用
python2.7或python3来调用解释器。
如果你实在需要为
python命令设置一个别名,请在个人shell配置文件中设置(如~/.bashrc),且仅限当前用户:# 例如,将python别名指向python2.7(不推荐长期使用,仅作临时便利) alias python=python2.7记住,这可能会影响某些系统脚本或IDE的默认行为。
- 不要修改系统默认的
5.3 你可能遇到的典型错误与解决思路
ImportError: No module named site:- 问题:通常在手动编译安装后,直接运行
python2.7时出现。 - 原因:Python找不到它的标准库路径。可能是在编译时
--prefix配置有问题,或者安装后相关环境变量(如PYTHONHOME)被意外设置。 - 解决:检查Python的安装路径和库路径。运行
/usr/local/python2.7/bin/python2.7 -c "import sys; print(sys.path)"查看搜索路径。确保安装目录结构正确(lib/python2.7等目录存在)。清除可能干扰的PYTHONHOME环境变量。
- 问题:通常在手动编译安装后,直接运行
pip2.7安装包时遇到SSL/TLS相关错误:- 问题:
pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available. - 原因:编译Python时没有正确链接到系统的OpenSSL库。在编译前的
./configure阶段,可能因为缺少libssl-dev包而自动禁用了ssl模块。 - 解决:必须重新编译。确保已安装
libssl-dev,然后在源码目录执行make clean,再重新运行./configure和make。可以在configure后查看输出,确认ssl模块是否被检测到并启用。
- 问题:
使用虚拟环境时,
virtualenv命令找不到python2.7:- 问题:
RuntimeError: failed to find interpreter for Builtin discover of python_spec='python2.7' - 原因:
virtualenv在系统PATH中找不到名为python2.7的可执行文件。 - 解决:确保你的Python 2.7安装路径(如
/usr/local/python2.7/bin或/usr/bin)已经包含在系统的PATH环境变量中。或者,在使用virtualenv命令时,使用解释器的绝对路径:virtualenv --python=/usr/local/python2.7/bin/python2.7 myenv。
- 问题:
6. 长期维护建议:是升级代码还是维持旧环境?
让Python 2.7在Ubuntu 24.04上跑起来只是第一步。从长远来看,你需要做一个更重要的决定:是继续维护这个陈旧的环境,还是着手将代码迁移到Python 3?
维持旧环境的成本:
- 安全风险:Python 2已停止官方安全更新,任何新发现的漏洞都不会被修复。如果你的应用暴露在网络中,风险会随时间增加。
- 依赖断裂:越来越多的第三方库停止对Python 2的支持,你可能会发现无法安装新版本的关键库。
- 人才与工具:熟悉Python 2的开发者越来越少,新的开发工具和IDE对Python 2的支持也在减弱。
- 系统兼容性:正如本文所讨论的,未来新版的Ubuntu或其他Linux发行版,会让安装Python 2变得越来越困难。
升级到Python 3的路径: 如果项目代码量不大,强烈建议启动迁移。Python官方提供了2to3工具可以自动转换大部分语法差异。迁移的主要挑战通常不在于语法,而在于:
- 字符串/字节处理:Python 3严格区分
str(Unicode) 和bytes。 - 字典迭代方法:
dict.keys(),.values(),.items()返回视图而非列表。 - 打印函数:
print变为函数。 - 整数除法:
/总是返回浮点数,//用于整除。 - 第三方库:检查所有依赖库是否有Python 3版本。
一个务实的策略是:为新功能或主要重构使用Python 3编写,对于暂时无法替换的旧核心模块,则利用本文的方法在隔离环境(尤其是Docker)中继续运行Python 2.7,同时制定一个逐步迁移的计划。
最终,在Ubuntu 24.04上安装Python 2.7,更像是一种“考古”或“过渡期”的技术手段。它让你有能力继续运行那些尚未完成迁移的宝贵遗产代码,但同时也应该作为一个明确的信号,提醒你是时候认真规划未来的技术栈了。通过本文介绍的几种方法,特别是Docker容器化方案,你可以在确保当前业务稳定的前提下,为这场必要的升级赢得宝贵的时间和空间。