概述
最近在将 Python3.6 升级为 Python3.9,记录下过程。 由于服务器环境均无法连接互联网,故采用从可联网机器上下载安装包再上传至服务器离线编译安装的方式。
本文默认没有专职服务器运维人员,个人拥有服务器所有权限。(有专业人员哪还用得着自己装。。ORZ)
下文在 CentOS 7.8
中实测成功。
依赖
在安装 Python 时,程序会依赖一些系统程序。为了能正确安装,需要提前将这些依赖装好。
可以在 这里 按照系统版本和所需包搜索下载。
ps: 说实话,其实装的时候还是有点慌的
以 CentOS 7.8 为例,其他系统版本需编译试错、搜索 编译工具 (使用的是系统自带的)
- gcc == 4.8.5
- make == 3.82
系统依赖
- zlib-devel # 影响 zlib 包的安装
- libffi-devel # 忘了影响啥,装就对了
- openssl-devel # 影响 _ssl 包的安装,如果装了这个还是无法正确安装,则可以看 后文附录部分
- bzip2-devel # 影响 _bz2 包的安装
The necessary bits to build these optional modules were not found:
_bz2 _curses _curses_panel
_dbm _gdbm _hashlib
_lzma _sqlite3 _ssl
_tkinter _uuid readline
zlib
_ctypes - libffi-devel
_bz2 - bzip2-devel
_uuid - uuid-devel/libuuid-devel 前者好像和gdbm-devel有冲突
_lzma - xz-devel
_dbm - gdbm-devel
zlib - zlib-devel
readline - readline-devel
_hashlib - openssl11
_ssl - openssl11
下载
Python官方下载地址:https://www.python.org/downloads/
Python官方 ftp 下载地址:https://www.python.org/ftp/python/
可以按需下载相应的 Python 版本,由于是要在 Linux 中编译安装,所以我们需要下载 Gzipped source tarball
或者 XZ compressed source tarball
,前者是 .tgz
格式,后者是 .tar.xz
,正确解压后的结果无本质区别。
每个大版本中较新的版本建议从 ftp 中下载,downloads 中不是很全。
需要注意的是,Python 的同一个大版本在绝大多数情况下对于第三方包来说区别不大,
即 Python 3.9.*
中所有的版本,绝大部分情况都可以通用,差别细节详见官网版本介绍。
解压
下载之后我们就会得到一个类似 Python-3.9.13.tgz
这样的文件,将其上传到服务器之后,随便在一个地方进行解压即可,这个文件可以理解为一个安装包,具体安装到哪里需要后续配置。
$ cd /path/to/xxx
$ tar -xvf Python-3.9.13.tgz
配置
然后进入到解压出的文件夹中,开始配置安装规则。
常用的参数就是 --prefix
这个参数,它决定了Python将被安装在哪里。
如果不填,将会默认安装到 /usr/local/python
中,如此则后面的编译安装命令需要root权限,但一般 不建议 这样,因为如此可能会导致将操作系统之前已有的 Python 强制覆盖,引发一系列不可控的问题。
该示例如果完成安装,则 Python 命令的可执行文件位置是 /home/app/depends/python/py39/bin/python3.9
$ cd Python-3.9.13/
$ ./configure --prefix=/home/app/depends/python/py39
配置成功后,可能会有类似下文这样的建议,但笔者亲测,当 gcc 版本比较低时(比如本例中的4.8.5),使用该建议无法编译成功。所以建议低版本的 gcc 不要使用 --enable-optimizations
参数。
If you want a release build with all stable optimizations active (PGO, etc),
please run ./configure --enable-optimizations
编译
配置如果没有问题,就可以开始编译了,如果安装到了系统目录下则需要root权限。
$ make
如果依赖没有安装,或者遗漏,那么配置、编译这两步可能需要反复几次。
判断自己需要的内置包能不能正常安装,就需要看 make 的执行结果,最后下面一块的内容会有类似下面这样的输出。如果其中没有 Failed
或者 error
等关键词出现,并且 necessary
中缺少的包你未来也用不到,那么恭喜你可以进行下一步 安装 了。
Python build finished successfully!
The necessary bits to build these optional modules were not found:
_tkinter
To find the necessary bits, look in setup.py in detect_modules() for the module's name.
The following modules found by detect_modules() in setup.py, have been
built by the Makefile instead, as configured by the Setup files:
_abc atexit pwd
time
示例中的这次编译意味着,_tkinter
由于缺少相应的依赖,将不会被安装。搜索后得知,缺少 tkinter
这个包,可以参照上文 依赖 进行安装。
具体哪些包依赖什么,可以以这样的关键词搜索: [系统版本] [Python版本] [缺失的包名] not found
,以 _tkinter
为例,即 CentOS7 Python3 _tkinter not found
。
如果是国外或开源的操作系统(RedHat、CentOS、Arch、Ubuntu等)建议使用 Google,无法科学上网则建议使用 bing 国际版。如果是国内自主开发的系统,建议使用bing,且尽可能看官方建议。
拒绝百度,从我做起。
安装
一般来说,编译能过,而且不缺依赖,则安装就会比较顺。所以,请尽可能确保编译无误后,最后再执行安装。
$ make install
没报错就算成功,如果配置时用了 --prefix
参数指定了一个 不在 $PATH
中的地址,则会有下面这样的提示。
意思是,没办法直接用 python
命令直接执行刚刚安装好的程序。
Installing collected packages: setuptools, pip
WARNING: The scripts pip3 and pip3.9 are installed in '/path/to/python/bin' which is not on PATH.
Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed pip-22.0.4 setuptools-58.1.0
查看 PATH 命令
$ echo $PATH
如果需要在终端直接执行 python
,这里提供两种方法来实现。
- 使用软连接
可以使用软连接将刚刚安装的 Python 放到
$PATH
中的某个路径下,类似创建了一个快捷方式。 比如,安装目录为/new/path/to/python
,PATH 中有的路径/xxx/xxx
$ ln -s /new/path/to/python/bin/python3.9 /xxx/xxx/python3.9
$ ln -s /new/path/to/python/bin/pip.9 /xxx/xxx/pip3.9
- 直接将安装目录放到 PATH 中
假设默认 shell 是 bash,安装目录为
/new/path/to/python
。则修改该用户的 .bashrc 文件即可。
$ vim ~/.bashrc
~/.bashrc
export PATH=/new/path/to/python/bin:$PATH
保存文件后,执行
$ source ~/.bashrc
以后该用户就可以直接使用 python3.9
命令了。
附录
当时的情况是,通过 yum
安装 openssl-devel
之后,在安装 Python3.9
时 ssl
模组仍无法正确安装(猜测是openssl版本过低,时间久远有点忘记细节了),故使用编译安装的方式,重新装了一个 openssl-1.1.1
,再在编译 Python 时使用 --with-openssl
参数,最后 ssl 成功安装。
下为当时的操作记录.
615 tar -zxvf openssl-1.1.1t.tar.gz
616 ll
617 cd openssl-1.1.1t/
618 ll
619 ./Configure -h
620 ./config -h
625 cd /path/xxxxx
626 mkdir openssl
627 pwd
628 cd -
629 ./config --prefix=/path/to/openssl --openssldir=/path/to/openssl
630 make
631 make install
632 cd -
633 ll openssl/
634 cd -
635 cd ..
636 cd Python-3.9.13/
646 ./configure --prefix=/path/to/py39 --with-openssl=/path/to/openssl
647 make
648 make install
649 /path/to/python3.9
650 whereis python
664 echo $PATH
670 ln -s /path/to/py39/bin/python3.9 /path/in/$PATH/python3.9
671 ln -s /path/to/py39/bin/pip3.9 /path/in/$PATH/pip3.9
673 python3.9