ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

CentOS上源码编译安装高版本Python全流程指南

CentOS上源码编译安装高版本Python全流程指南 给Centos的服务器装高版本Python我折腾过太多次了每一次都会碰到新朋友问同样的问题为什么yum install python3装出来还是3.6为什么源码编译老报错为什么装完了python命令还是旧版本今天就一次性把这些事情讲清楚从准备工作到编译参数从环境配置到排查技巧完整过一遍。如果你手头正好有一台Centos 7或Centos 8 Stream的机器跟着操作基本能一次成功。先说个关键结论Centos系统自带的Python版本普遍偏老想用上3.9以上的Python最靠谱的方式是源码编译安装。系统自带Python是给yum、dnf这类系统工具用的动它容易搞崩整个系统。而第三方yum源虽然可以一键装高版本但又受制于源的维护状态。所以这篇文章主推编译安装同时对比一下其他方案你把原理和流程都理解透了以后在别的Linux发行版上也一样能举一反三。1. 为什么Centos上装个新Python这么费劲1.1 自带版本到底有多老Centos 7默认Python版本是2.7.5这个版本发布于2013年官方的安全维护在2020年初就停止了。Centos 8默认Python 3.6.8看着比2.7年轻不少但3.6的完整生命周期也在2021年底就结束了。Centos 8 Stream默认同样是3.6.8而目前Python官方主推的稳定版早就到了3.12、3.133.8以下的版本都已经停止更新。问题的严重性不只是版本号旧而是系统工具和Python深度绑定。Centos 7的yum依赖Python 2.7Centos 8的dnf干脆就是Python 3写的。如果你图省事直接替换系统的python命令yum和dnf立刻罢工连装包都装不了那就真是自己把自己锁死了。这就像一套老房子的承重墙不能随便拆——系统Python就是那面承重墙拆了房子就塌了。所以我们装高版本Python的思路不是在原地换新而是在旁边另起一栋楼新的、旧的共存互不干扰。1.2 高版本Python到底带来了什么很多朋友问我用Python 3.6写脚本也没觉得不好啊为什么非要升我用几个实际场景说明新项目依赖新版本当前主流框架Django 4.2要求Python 3.8以上FastAPI要求3.8以上新版requests也放弃了对3.7以下的支持。你拿3.6去pip install最新依赖大概率直接报错。语法和性能差距明显Python 3.8引入的海象运算符:、3.10引入的match模式匹配、3.11的异常组这些新语法让代码的写法更简洁。性能上Python 3.11比3.8平均快25%左右跑数据处理任务时差距能明显感受到。安全修复老版本Python存在公开的已知漏洞如果机器暴露在公网使用已停止维护的Python版本风险是实打实的。这几个原因叠加在一起就是一个结论在Centos上装高版本Python不是可选项而是刚需。1.3 装新Python的三条路线围绕这个刚需市面上大致有三条路yum install python3直接装Centos 7给的是Python 3.6.8Centos 8给的还是3.6.8都是老版本满足不了新项目的要求。第三方yum源像是IUS社区源、SCL软件集合可以装到3.8、3.9甚至更新的版本。好处是一条yum命令就能完成坏处是这些源的维护状态需要自己盯有的源在系统大版本升级后就停止更新了依赖冲突时排查起来比较麻烦。源码编译安装从Python官网下载源码包自己配置、编译、安装到独立目录。过程最长但最可控——版本想选哪个选哪个安装路径自己定和系统自带Python完全隔离。这篇文章主推第三条路。第三条路走得通你也就理解了为什么一些老手总爱说编译安装yyds。2. 动手前的准备工作2.1 先看清自己的系统底细开工前先确认系统版本和当前Python情况避免后面配置错路径。依次执行这几条命令cat /etc/redhat-release python --version python3 --version which python which python3cat /etc/redhat-release会显示系统发行版本比如Centos Linux release 7.9.2009 (Core)或者Centos Stream release 8。后面的几条命令用来确认当前Python指向和版本。我见过不少情况是python指向2.7python3指向3.6但两个都不是我们想要的。这一步做好记录。特别是记住系统自带python3的路径一般是/usr/bin/python3后面配置PATH时不要覆盖它也不要改动它。2.2 把编译环境一次配齐编译Python是一系列C代码的构建过程编译器、头文件、依赖库缺一不可。直接一条命令装齐所有依赖yum install -y gcc gcc-c make wget \ openssl-devel zlib-devel bzip2-devel \ readline-devel sqlite-devel ncurses-devel \ tk-devel gdbm-devel libffi-devel \ xz-devel如果你用的是Centos 8 Stream或者系统提示找不到yum命令就用dnf install -y参数完全一样。这里面的每个依赖包都不是白装的。我按重要性给它们排个序方便你理解为什么缺了某个包会出问题依赖包对应Python模块缺了会怎样gcc / gcc-c / make整个编译过程Python源码根本无法构建zlib-develzlib压缩安装阶段解压模块报zipimport.ZipImportErrorlibffi-develctypes编译完成后报No module named _ctypesopenssl-develssl / hashlib编译好的Python没有SSL支持pip无法访问HTTPS源sqlite-develsqlite3报No module named _sqlite3readline-develreadline交互行编辑进入Python交互式终端时方向键乱码这里面最容易被忽略的是libffi-devel因为很多教程只让你装gcc openssl-devel zlib-devel这几样。等你花几十分钟编译完一运行import ctypes直接报错还要重新编译浪费时间。所以我在自己的实践里习惯把依赖一次性装齐宁多勿漏。2.3 选定版本并下载源码版本选型我给出实际建议2024年这个时间点生产环境优先选Python 3.10或3.11新项目可以尝试3.12但不太建议追最新的3.13。3.10经过了两年多的生态验证绝大多数第三方库都已经兼容3.11性能提升明显也是目前很稳的选择。3.12发布还不到一年部分底层库可能还没跟上。下载地址在Python官网官网下载页用wget直接拉取指定版本比如3.10.12mkdir -p /opt/src cd /opt/src wget https://www.python.org/ftp/python/3.10.12/Python-3.10.12.tgz ls -l Python-3.10.12.tgz把源码包都放到/opt/src方便统一管理以后装了多个版本也好找。下载完成后你可以用md5sum Python-3.10.12.tgz和官网公布的校验值比对一下防止文件不完整。这一步我一般顺手就做了几秒钟的事能省掉后面莫名其妙报错的麻烦。3. 编译安装全流程实操3.1 解压和配置configure参数源码包下载好之后先解压并进入目录cd /opt/src tar -zxvf Python-3.10.12.tgz cd Python-3.10.12真正的核心步骤是执行configure脚本。这个脚本的作用是检查编译环境、检测依赖库、生成编译所需的Makefile。我的标准配置是./configure \ --prefix/usr/local/python310 \ --enable-optimizations \ --with-ensurepipinstall三个参数逐个解释--prefix/usr/local/python310指定Python安装目录。所有编译好的二进制、库文件、头文件都会放到这个目录下面。选这个路径的好处是版本信息一目了然python310就是3.10升级或删除时直接删整个目录即可。--enable-optimizations开启PGOProfile-Guided Optimization优化。简单说编译器先跑一遍测试程序收集热点数据再根据这些数据做针对性优化编译出来的Python运行速度快一些。代价是编译时间明显变长如果你只是本地开发用、在意安装速度可以去掉这个参数。--with-ensurepipinstall编译时自带安装pip省得后面手动引导。这个参数对我来说基本必加。还有一个不常用的参数值得知道--enable-shared它会生成Python动态链接库。如果你计划让C程序嵌入Python解释器会需要它。但对普通使用场景来说这个参数会引入动态链接库搜索路径问题所以我个人不推荐除非明确需要。如果你用的系统openssl版本特别老比如Centos 7默认的OpenSSL 1.0.2编译Python 3.10以上的版本时会提示找不到合适的OpenSSL从而禁用SSL模块。这种情况下面第5节我会专门讲排查方法先按这条标准流程走。3.2 编译和安装关键一步altinstallconfigure执行完后目录里会生成Makefile下一步就是编译。用多核并行编译可以省大量时间make -j$(nproc)-j$(nproc)的意思是自动检测CPU核心数并行编译。我的一台4核机器编译Python 3.10不开优化大约10分钟开了--enable-optimizations之后要35到40分钟。如果编译中途报错先别急着重跑往下翻滚看日志里真正的错误信息第5节我会展开讲。编译完成后安装步骤一定要用make altinstall而不是make installmake altinstall原因非常关键make install会把编译产物安装成python3、pip3这样的通用命令名和系统里已有的Python命令冲突而make altinstall只安装带版本号的名字比如python3.10、pip3.10不会去覆盖/usr/bin/python3。这里多说一句altinstall里的alt是alternate的意思官方就是设计来让你安全地装新版Python的。我看到有人装完Python后系统yum崩溃十有八九就是用了make install。记住这条铁律别用make install用make altinstall。3.3 把新Python的路径配好安装完成后新Python在/usr/local/python310/bin/下面主要文件是python3.10和pip3.10。此时直接输入python3.10能不能用取决于PATH里有没有包含/usr/local/python310/bin。推荐把配置写到全局环境变量文件里这样对所有用户都生效cat /etc/profile.d/python310.sh EOF export PATH/usr/local/python310/bin:$PATH EOF source /etc/profile.d/python310.sh紧接着验证三个关键点python3.10 --version which python3.10 python3.10 -m pip --version如果显示Python 3.10.12并且python3.10路径来自/usr/local/python310/bin说明安装成功。注意不用去改/usr/bin下面的任何软链接。系统自带python3继续服务系统工具你新增的高版本Python独立运行大家相安无事。4. 多版本共存的日常管理4.1 管理多个Python版本的三层思路装好了Python 3.10系统里同时会有2.7Centos 7或3.6Centos 8、以及可能你后来又装的3.11多个版本并存怎么管这里分三个层次来说第一层直接用带版本号的命令python3.10这是最简单也最不会出错的方式。Python官方设计了python3.x这种带小版本号的命令名核心用意就是让多个版本优雅共存。第二层调整PATH控制默认python3指向谁的版本。我在上面配置的export PATH/usr/local/python310/bin:$PATH把新版本路径放在前面。这样你输入python3系统会先在/usr/local/python310/bin里找找到的就是3.10。但这条只对你新安装的这个版本有效。如果你装了3.11、3.12好几个版本PATH里谁在前谁就是默认所以这种方式需要你心里有数。第三层用alternatives工具做统一管理。如果你有多个版本且需要频繁切换默认版本可以注册进系统替代机制alternatives --install /usr/bin/python3 python3 /usr/local/python310/bin/python3.10 310 alternatives --install /usr/bin/python3 python3 /usr/local/python311/bin/python3.11 311 alternatives --config python3后面那个数字是优先级数字越大优先级越高。执行alternatives --config python3后可以交互式选择默认版本。这种方式适合团队共用服务器大家需要一个明确的默认版本时。4.2 让pip跟着正确的人走很多朋友在pip上踩坑明明装了Python 3.10执行pip install xxx却装到了系统自带Python 3.6的目录里。原因在于pip这个命令名本身指向不明确——系统中可能有pip2.7、pip3.6、pip3.10。我的建议是始终用模块方式调用pip永远不要裸调pippython3.10 -m pip install --upgrade pip python3.10 -m pip install requestspython3.10 -m pip的意思是告诉解释器运行pip模块这条命令天然绑定了Python 3.10的解释器装到哪个site-packages一目了然。否则你费半天劲查pip版本号查到的也未必是你在用的那个Python对应的pip。新装的Python自带pip版本可能偏旧所以第一次使用建议先升级。装包的时候如果提示版本冲突或者找不到匹配版本也可以检查一下是不是pip本身版本太老——先把pip升级到新版本再重试能解决相当一部分问题。4.3 虚拟环境是必须学会的一课版本管理到更深一层你就会遇到依赖隔离的问题。A项目要用Django 4.2B项目只能用Django 3.2如果全装到全局环境里版本冲突能把人折磨疯。虚拟环境就是为此而生的。创建虚拟环境现在不需要装第三方工具Python 3自带的venv模块就能做cd /opt/myproject python3.10 -m venv venv source venv/bin/activate激活虚拟环境后命令行提示符前面会出现(venv)之后在这个终端里的pip install都装进虚拟环境不会污染全局Python。退出也很简单执行deactivate。我个人的习惯是全局Python只装基础工具比如pip、ipython凡是有项目的依赖一律丢进虚拟环境。不管是日常开发还是服务器上跑服务这个习惯让我少踩了无数依赖冲突的坑。特别是Centos这种系统Python版本老的环境虚拟环境简直就是隔离矛盾的隔音墙。5. 那些年我踩过的坑和排查技巧5.1 编译时最常见的四类报错编译报错是最劝退新手的关卡但其实多数报错的原因非常集中。我按出现频率列几个典型的报错一zipimport.ZipImportError: cant decompress data这个通常在编译后期安装阶段出现原因是缺少zlib依赖。处理办法很简单yum install -y zlib-devel然后重新从configure开始编译。报错二编译完成后import ctypes报ModuleNotFoundError: No module named _ctypes这是缺libffi-devel导致的。很多人编译时没装这个包等装完了运行某个程序才暴雷。处理方法是yum install -y libffi-devel然后make clean ./configure make make altinstall重来一遍。报错三ModuleNotFoundError: No module named _ssl这个分两种情况。一种是你忘了装openssl-devel直接装上重编即可另一种是系统openssl版本太老比如Centos 7自带的OpenSSL 1.0.2给Python 3.10编译时就有兼容性问题。后者的一个可行方案是给系统openssl升级到1.1.1以上但这对系统影响比较大需要谨慎评估。另一个思路是单独编译一个新版本OpenSSL到独立目录然后在编译Python时通过--with-openssl/path/to/openssl指定路径。这个操作细节较多生产环境建议先在测试机验证。报错四ModuleNotFoundError: No module named _sqlite3缺sqlite-devel导致的。yum install -y sqlite-devel后重新编译。遇到编译报错我判断的一个技巧是只关注make输出里最后几行和Error关键字附近的信息前面的刷屏警告大多无伤大雅。真正的错误往往会被summary或Traceback明确指出。把报错信息复制到搜索引擎里加上Centos关键词大概率能找到现成答案因为这条路上的坑几乎所有人都踩过。5.2 装完了python命令还是旧版本这种情况也超级常见。可能的原因有三个第一bash命令缓存。bash会缓存命令的路径如果当前shell是在安装之前加载的PATH虽然已经变更但缓存还是旧路径。解决办法是执行hash -r或者干脆开一个新终端窗口。第二PATH配置没生效。检查一下echo $PATH里有没有包含/usr/local/python310/bin而且要在系统路径前面。如果没生效确认一下.bashrc、.bash_profile或者/etc/profile.d的配置文件是否加载了。全局配置文件需要重新登录才完全生效。第三系统自带python3优先级更高。输入which python3看看路径——如果显示/usr/bin/python3说明PATH里系统路径排在了你新增路径前面。可以通过echo export PATH/usr/local/python310/bin:$PATH重新设置确保新路径在最前。5.3 别手贱改系统Python软链接这是我见过翻车案例最多的地方。有些教程会让你把/usr/bin/python软链接指向新版Python试过的人基本都付出了惨痛代价yum命令直接报错、firewalld启动失败、系统工具连环出错。原因在于Centos 7的系统管理工具链是以Python 2.7为基础的yum本身就是一个Python 2.7脚本。你把/usr/bin/python从2.7改成3.10等于把yum的地基抽掉了。Centos 8虽然系统python3是3.6dnf依赖它但dnf内部有大量针对3.6的特性假设你把它改成3.10仍然可能出问题。正确做法就是我在3.3节里写的那样通过PATH环境变量让新Python的命令名优先被找到而不是去动系统文件。如果你之前已经改了软链接导致系统工具崩溃也不用慌把软链接恢复成原来的指向即可Centos 7是ln -sf python2.7 /usr/bin/pythonCentos 8是ln -sf python3.6 /usr/bin/python3。5.4 排查工具三板斧遇到问题别瞎猜先收集信息。我的习惯是依次执行which python3.10 echo $PATH ldd /usr/local/python310/bin/python3.10 | grep not found第一句确认你用的命令到底来自哪个路径第二句看PATH顺序第三句用ldd检查动态库依赖是否完整。ldd | grep not found如果输出了内容说明某些动态库缺失或路径不对前面的依赖安装环节就要重新检查。这个方法比我见过的大多数凭经验猜测高效得多。动态库问题在Centos上尤其常见因为新旧Python对库版本的要求不同而ldd一眼就能看清楚。6. 第三方源方案和我的最终建议6.1 想更省事可以试试这些yum源除了源码编译还有一个相对小众但确实可行的方案就是配置第三方yum源。比如IUS源提供更新的Python版本Centos 7上可以这样用yum install -y https://repo.ius.io/ius-release-el7.rpm yum install -y python310SCL软件集合也是类似思路启用之后用yum install rh-python310装使用时需要通过scl enable rh-python310 bash临时切换环境。这类方案的优势是安装快、不涉及编译过程。但局限也很明显源本身的维护状态决定了你能否持续获得更新。我见过有朋友用第三方源装了Python 3.8结果源停止维护了后续安全更新完全断档还得回归源码编译。所以我个人把它定位成临时解决方案长期使用还是得走官网源码编译。还有一点提醒配置第三方源时不要贪多一个系统源配一个第三方源就够了。源配多了依赖解析冲突的风险成倍增加到时候yum install都可能报依赖错误排查起来相当头疼。6.2 我的最终建议综合下来我的结论很明确在Centos上安装高版本Python首选源码编译注意三点——一次性装齐依赖、用altinstall不用install、通过PATH而非软链接接入系统。这三条保证你一次编译成功且不会把系统搞乱。版本选型方面生产环境建议走3.10或3.11这种经过大量项目验证的稳定版本新项目可以尝鲜3.12。安装路径统一放到/usr/local/python3xx这样的目录每个版本官方都有独立目录方便日后升级和清理。日常使用中给每个项目建独立的虚拟环境用python3.10 -m pip而非裸pip这两个习惯能帮你避开90%的依赖管理问题。写在最后我个人在实际操作中最深的一个体会是别小看依赖准备环节。头几次编译失败十有八九不是因为编译参数写错而是因为某个-devel包没装。现在每次换新机器装Python我都会先对着依赖清单逐项核对再开始configure。这个习惯帮我省下了大量重复编译的时间。如果你正准备在一台Centos上安装高版本Python照着这篇文章的流程走一遍大概率比你看的任何碎片化教程都顺利。要是过程中还有没覆盖到的报错把你看到的错误信息贴在评论区我可以帮你分析。祝你在Centos上玩转新Python少踩坑多产出。
返回列表