我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Pythonvenv虚拟环境跨设备迁移的实现

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Pythonvenv虚拟环境跨设备迁移的实现

背景

我们通常会遇到想简易搬迁一台设备的python开发环境到另外一台设备的情况,但可能我们另一台设备本身的python环境包括系统环境是不可控的,这里我遇到的是从centos7搬迁python开发环境到centos6,centos7自带的python环境为2.7.5版本且一些依赖的文件库也是适配2.7.5版本及以上的,导致我们把环境搬迁到centos6的默认python2.6.6环境下时,产生了非常多的报错,以下文档内容记录我遇到的报错及解决方式,并提供一种较为完美的方式轻量级的解决环境移植问题。

python加载lib库的顺序

环境
制作python 虚拟环境设备:

  • 系统版本:centos 7
  • python版本:python2.7.5

移植的目标设备:

  • 系统版本:centos 6
  • python版本:python2.6.6

详细操作

安装virtualenv

[centos 7] # pip install virtualenv

创建python venv环境

[centos 7] # mkdir -p /opt/python_venv_test
[centos 7] # virtualenv -p /usr/bin/python2.7 --copies /opt/python_venv_test

--copies的参数意思为尽量不要为/opt/python_venv_test的文件创建软链接,如果不指定该参数,我们可以看到/opt/python_venv_test目录有些文件就是这样的:

[centos 7] # ll /opt/python_venv_test/lib64/python2.7/*
lrwxrwxrwx 1 root root   32 Apr 26 20:24 /opt/python_venv_test/lib64/python2.7/lib-dynload -> /usr/lib64/python2.7/lib-dynload
lrwxrwxrwx 1 root root   26 Apr 26 20:24 /opt/python_venv_test/lib64/python2.7/os.py -> /usr/lib64/python2.7/os.py
lrwxrwxrwx 1 root root   27 Apr 26 20:24 /opt/python_venv_test/lib64/python2.7/os.pyc -> /usr/lib64/python2.7/os.pyc
-rw-r--r-- 1 root root 6978 Apr 26 20:24 /opt/python_venv_test/lib64/python2.7/site.py

/opt/python_venv_test/lib64/python2.7/config:
total 0
lrwxrwxrwx 1 root root 36 Apr 26 20:24 Makefile -> /usr/lib64/python2.7/config/Makefile

/opt/python_venv_test/lib64/python2.7/site-packages:
total 0

可以看到很多文件直接是做了软链接到原python 环境中的lib库中的文件,如果这个时候咱们把他打包移植到另外的设备,这些文件就全部都会被清空,所以一定要加--copies这个参数。加了--copies参数之后是这样的:

[centos 7] # ll -d /opt/python_venv_test/lib64/python2.7/*
drwxr-xr-x 2 root root  4096 Apr 26 20:31 /opt/python_venv_test/lib64/python2.7/config
drwxr-xr-x 2 root root  4096 Apr 26 20:31 /opt/python_venv_test/lib64/python2.7/lib-dynload
-rw-r--r-- 1 root root 25769 Apr 26 20:31 /opt/python_venv_test/lib64/python2.7/os.py
-rw-r--r-- 1 root root 25557 Apr 26 20:31 /opt/python_venv_test/lib64/python2.7/os.pyc
drwxr-xr-x 2 root root  4096 Apr 26 20:31 /opt/python_venv_test/lib64/python2.7/site-packages
-rw-r--r-- 1 root root  6978 Apr 26 20:31 /opt/python_venv_test/lib64/python2.7/site.py

可以看到没有软链接了,那么我们这个环境就是完全独立的,这时候我们的python venv环境就已经生成了。

打包依赖的glibc库

我们的python环境为python2.7.5版本,比较推荐的是使用glibc-2.17版本,下载地址为:glibc下载地址 ,里面有各个版本的glibc文件。

为什么这里要打包依赖的glibc库呢?

我把虚拟环境目录移植到目标的centos6机器上测试了一下,如果上面的这些库文件在新的设备上没有,那么就会报错,这里我遇到的报错就是:

/bin/python: error while loading shared libraries: libpython2.7.so.1.0: cannot open shared object file: No such file or directory

./bin/python: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by /usr/lib64/libpython2.7.so.1.0)

这两个报错都是很有可能会命中的,提示我们缺少库文件,没有办法运行python binary。

那么到底缺少哪些库文件呢?我们可以通过readelf -d /opt/python_venv_test/bin/python 命令检查python binary的依赖文件:

[centos 7] # readelf -d /opt/python_venv_test/bin/python

Dynamic section at offset 0xdd8 contains 29 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libpython2.7.so.1.0]
 0x0000000000000001 (NEEDED)             Shared library: [libpthread.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libdl.so.2]
 0x0000000000000001 (NEEDED)             Shared library: [libutil.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000c (INIT)               0x4005e0
 0x000000000000000d (FINI)               0x4007a4
 0x0000000000000019 (INIT_ARRAY)         0x600dc0
 0x000000000000001b (INIT_ARRAYSZ)       8 (bytes)
 0x000000000000001a (FINI_ARRAY)         0x600dc8
 0x000000000000001c (FINI_ARRAYSZ)       8 (bytes)
 0x000000006ffffef5 (GNU_HASH)           0x400298
 0x0000000000000005 (STRTAB)             0x400478
 0x0000000000000006 (SYMTAB)             0x4002f8
 0x000000000000000a (STRSZ)              218 (bytes)
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000015 (DEBUG)              0x0
 0x0000000000000003 (PLTGOT)             0x601000
 0x0000000000000002 (PLTRELSZ)           48 (bytes)
 0x0000000000000014 (PLTREL)             RELA
 0x0000000000000017 (JMPREL)             0x4005b0
 0x0000000000000007 (RELA)               0x400598
 0x0000000000000008 (RELASZ)             24 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x000000006ffffffe (VERNEED)            0x400578
 0x000000006fffffff (VERNEEDNUM)         1
 0x000000006ffffff0 (VERSYM)             0x400552
 0x0000000000000000 (NULL)               0x0

我们可以在两台机器上查看一下到底有没有库文件,以及库文件产出自哪个rpm包:

目标 centos 6机器没有找到libpython2.7.so.1.0库文件, 而/lib64/libc.so.6文件版本较低,没有达到glibc-2.14版本:

[centos 6] #  whereis libpython2.7.so.1.0
libpython2.7.so.1:

[centos 6] # whereis /lib64/libc.so.6
libc.so: /lib/libc.so.6 /lib64/libc.so.6 /usr/lib64/libc.so

[centos 6] # rpm -qf /lib64/libc.so.6
glibc-2.12-1.80.el6.x86_64

我们回到centos 7机器看看,可以看到有libpython2.7.so.1.0这个文件,而且/usr/lib64/libc.so.6的版本也大于glibc-2.14版本。

[centos 7] # whereis libpython2.7.so.1.0
libpython2.7.so.1: /usr/lib64/libpython2.7.so.1.0

[centos 7] #  rpm -qf /usr/lib64/libpython2.7.so.1.0
python-libs-2.7.5-68.el7.x86_64

[centos 7] #  whereis /lib64/libc.so.6
libc.so: /usr/lib/libc.so.6 /usr/lib64/libc.so /usr/lib64/libc.so.6
[centos 7] #  rpm -qf /usr/lib64/libc.so.6
glibc-devel-2.17-260.el7_6.3.x86_64

好了, 我们回归正题,我们现在要解决上面这些问题。

首先,在centos 7机器上,下载及安装glibc-2.17:

[centos 7] # wget http://ftp.gnu.org/gnu/glibc/glibc-2.17.tar.xz -O /tmp/
[centos 7] # cd /tmp/; tar xf glibc-2.17.tar.xz; cd /tmp/glibc-2.17
[centos 7] # mkdir build; cd build
[centos 7] # ../configure --prefix=/opt/python_venv_test/glibc-217
[centos 7] # make -j4
[centos 7] # make install

以上操作完成后,我们就可以在/opt/python_venv_test/glibc-217目录下看到glibc-2.17的所有文件都在里面了。然后我们把发现的不属于glibc但又需要的库文件libpython2.7.so.1.0移植进来glibc-2.17的lib目录里:

[centos 7] # cp -ar /usr/lib64/libpython2.7.so.1.0 /opt/python_venv_test/glibc-217/lib/

除了glibc这个基础库,还需要python本身的基础库,是运行binary python时需要加载的模块,比如os等,这个库一般是在系统的/usr/lib64/python2.7/目录,我们把它移植到我们的虚拟环境目录下(这个地方如果我们本地的/usr/lib64/python2.7 过大,可以考虑起一个可运行干净的python环境centos 7虚拟机,把它的/usr/lib64/python2.7拷贝过来,这样就能保证它是最小的包量):

[centos 7] # rm -rf /opt/python_venv_test/lib64/python2.7

[centos 7] # cp -ar /usr/lib64/python2.7 /opt/python_venv_test/lib64/python2.7

如果上面这个操作你没有做,可能就会遇到这样的报错:

[centos 7] # ./bin/python
Could not find platform independent libraries <prefix>
Could not find platform dependent libraries <exec_prefix>
Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]
ImportError: No module named site

当你把$PYTHONHOME设置完成后,或者会遇到这样的报错(总之就是找不到基础库文件):

[centos 7] # ./bin/python
Traceback (most recent call last):
  File "/home/zhaoqiang09/bsc_python_venv.b/lib64/python2.7/site.py", line 190, in <module>
    main()
  File "/home/zhaoqiang09/bsc_python_venv.b/lib64/python2.7/site.py", line 18, in main
    rewrite_standard_library_sys_path()
  File "/home/zhaoqiang09/bsc_python_venv.b/lib64/python2.7/site.py", line 97, in rewrite_standard_library_sys_path
    import os
ImportError: No module named os

改写环境加载文件/opt/python_venv_test/pyvenv.cfg,这样我们就不需要依赖移植后目标centos 6系统本身的lib库了,以免造成版本冲突:

home = /opt/python_venv_test/
implementation = CPython
version_info = 2.7.5.final.0
virtualenv = 20.13.0
include-system-site-packages = false
base-prefix = /opt/python_venv_test/
base-exec-prefix = /usr
base-executable = /opt/python_venv_test/bin/python

我们还得改写一下/opt/python_venv_test/bin/activate 文件,这个文件是我们在移植后目标centos 6系统加载python虚拟环境的入口,我们在这里面加一条对LD_LIBRARY_PATH环境变量的局部重写(红色字体部分,第一条是为了退出环境变量时,下掉alias的绑定,第二条是开始加载activate环境时对LD_LIBRARY_PATH环境变量的局部重写):·

··········

deactivate () {
    unalias python >/dev/null 2>&1
    unset -f pydoc >/dev/null 2>&1 || true

·············

# Make sure to unalias pydoc if it's already there
alias pydoc 2>/dev/null >/dev/null && unalias pydoc || true
alias python="${VIRTUAL_ENV}/glibc-217/lib/ld-2.17.so --library-path ${VIRTUAL_ENV}/glibc-217/lib:/lib64 ${VIRTUAL_ENV}/bin/python"

·················

然后,我们就可以打包了:

[centos 7] # cd /opt/

[centos 7] # tar -czf python_venv_test.tar.gz python_venv_test

移植包到目标Centos 6系统上执行

首先在centos 7 系统上我们scp压缩包到目标机器

[centos 7] # cd /opt/

[centos 7] # scp python_venv_test.tar.gz root@centos_6:/opt/python_venv_test.tar.gz

然后我们在centos 6上解压压缩包:

[centos 6] # cd /opt/

[centos 6] # tar xf python_venv_test.tar.gz

这时候就可以虚拟环境目录运行python了

[centos 6] # cd /opt/python_venv_test

[centos 6] # souce bin/bin/activate

[centos 6] # python
Python 2.7.5 (default, Apr 11 2018, 07:36:10)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>

我们要扩充一些第三方扩展包

回到centos7机器

搬迁新增的flask、requests、psutil等第三方库

我们还是先回到我们的虚拟环境目录/opt/python_venv_test下面,先使用bin目录下的pip安装flask

# ./bin/pip install flask requests psutil

打压缩包,并拷贝压缩包到centos 6目标系统上

cd /opt/

tar -czf python_venv_test.tar.gz python_venv_test/

[centos 7] # scp python_venv_test.tar.gz root@centos_6:/opt/python_venv_test.tar.gz

回到centos6 机器上,解压缩包,并运行python看看有没有什么问题

cd /opt/python_venv_test/

# source bin/activate

# python
Python 2.7.5 (default, Apr 11 2018, 07:36:10)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import flask
bash: /opt/bsc_python_venv/glibc-217/lib/libssl.so.10: No such file or directory

报错显示缺少libssl.so.10文件,我们看看这个文件分别在两台测试机的哪里:

centos 6机器情况:

# whereis libssl.so.10
ld-2.17:

centos 7机器情况,并且要确定的是它不是一个软链接:

# whereis libssl.so.10
libssl.so: /usr/lib64/libssl.so.10 /usr/lib64/libssl.so

# ll -d /usr/lib64/libssl.so.10
lrwxrwxrwx 1 root root 16 Jan 21  2021 /usr/lib64/libssl.so.10 -> libssl.so.1.0.2k

# ll -d /usr/lib64/libssl.so.1.0.2k
-rwxr-xr-x 1 root root 470360 Mar 12  2019 /usr/lib64/libssl.so.1.0.2k

我们再把centos7 的 /usr/lib64/libssl.so.1.0.2k 这个文件给放到虚拟环境glibc-217目录,然后做成压缩包,传到centos6机器上,再来试试

# cp -ar /usr/lib64/libssl.so.1.0.2k /opt/python_venv_test/glibc-217/lib/libssl.so.10

# cd /opt/

# tar -czf python_venv_test.tar.gz python_venv_test/

[centos 7] # scp python_venv_test.tar.gz root@centos_6:/opt/python_venv_test.tar.gz

我们再在centos 6的机器上把原来的文件删除,解压缩,再试试import flask、requests、psutil这三个库文件,就不会再报刚才那个错了:

cd /opt/python_venv_test/

# source bin/activate

# python
Python 2.7.5 (default, Apr 11 2018, 07:36:10)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import flask
>>> import requests
>>> import psutil

结束! 

本文设计的内容较多,如果有一些细节不太懂的地方,建议自行搜索,再回来反复查看本文档。

到此这篇关于Python venv虚拟环境跨设备迁移的实现的文章就介绍到这了,更多相关Python venv迁移内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Pythonvenv虚拟环境跨设备迁移的实现

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Python虚拟环境迁移的实现

本文主要介绍了Python虚拟环境迁移的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2023-03-06

Python虚拟环境迁移如何实现

本篇内容介绍了“Python虚拟环境迁移如何实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!使用python开发脚本使用的时候难免会遇到需
2023-07-05

Python 虚拟环境迁移到其他电脑的实现

本文主要介绍了Python 虚拟环境迁移到其他电脑的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2023-05-15

Python虚拟环境迁移的方法是什么

在Python中,可以使用pip工具来导出虚拟环境的依赖项列表,并在新环境中重新安装这些依赖项。以下是迁移Python虚拟环境的一般步骤:在原始环境中导出依赖项列表:pip freeze > requirements.txt在新环境中创建虚
Python虚拟环境迁移的方法是什么
2024-04-09

Python虚拟环境迁移的方法是什么

Python虚拟环境迁移迁移Python虚拟环境涉及将现有虚拟环境及其依赖项从一台计算机转移到另一台计算机。此过程可用于在开发和生产环境之间移动、进行测试或创建备份。迁移步骤包括导出虚拟环境、复制导出的目录、创建新虚拟环境、导入导出目录并重新激活环境。其他方法包括使用pipfreeze/pipinstall或venvpack打包和解包环境。
Python虚拟环境迁移的方法是什么
2024-04-13

JupyterLab设置切换虚拟环境的实现步骤

本文主要介绍了JupyterLab设置切换虚拟环境的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2023-02-08

Conda中环境迁移到另一个服务器的实现

本文主要介绍了Conda中的环境迁移到另一个服务器,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2023-03-13

conda配置python虚拟环境的实现步骤

本文主要介绍了conda配置python虚拟环境的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2023-03-19

Bokeh怎么可视化虚拟现实环境中的数据

在虚拟现实环境中,Bokeh可以通过以下方法来可视化数据:使用虚拟现实技术创建3D场景:首先,利用虚拟现实技术(如Unity、Unreal Engine等)创建一个3D场景,可以是一个虚拟环境、虚拟地图或者其他的3D空间。将数据转换为3D模
Bokeh怎么可视化虚拟现实环境中的数据
2024-05-21

使用虚拟环境实现Python版本和依赖库的兼容

这篇文章主要介绍了使用虚拟环境实现Python版本和依赖库的兼容的相关资料,需要的朋友可以参考下
2022-12-08

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录