pipenv+virtualenv配置全新的python环境

提示信息说三遍,本文最终的结果并不如人意,只是一些探索的过程记录。问题在于:当使用paramiko库时会提示openssh服务,而如果继续封装就有点违背当初的想法,应该有更优秀的解决方案。

提示信息说三遍,本文最终的结果并不如人意,只是一些探索的过程记录。问题在于:当使用paramiko库时会提示openssh服务,而如果继续封装就有点违背当初的想法,应该有更优秀的解决方案。

提示信息说三遍,本文最终的结果并不如人意,只是一些探索的过程记录。问题在于:当使用paramiko库时会提示openssh服务,而如果继续封装就有点违背当初的想法,应该有更优秀的解决方案。

pipenv+virtualenv配置全新的python环境

如果需要用python写个项目,并且允许其运行在稍低版本的Linux下,需要构建一套完整的虚拟环境,这中间有许多坑,花了一个星期终于打包出来了。

总的来说,

  • 首先需要构造完整的python环境
  • 再构造一个虚拟环境以便于启动
  • 打包相应的glibc包
  • 执行指令时用绝对路径来运行命令。

全篇遇到了不少坑,主要依据这篇文章进行操作制作python虚拟环境包,大体上没有什么问题,但是更注重于操作,而缺少一些解释,以及没有glibc包的打包过程。

创建完整的python环境

如果只是用virtualenv或者pipenv等工具直接创建虚拟环境,那么虚拟环境中的很多.py文件都只是软连接指向系统自带的python环境对应的.py文件。

这样的话,即便虚拟环境ok了,在另一个python版本不对或者没有python环境的机器上就会找不到对应的位置而报错。

可以通过查看虚拟环境中的lib目录得知指向的位置,

所以在创建虚拟环境前需要创建完整的python环境。

由于那篇博客关于安装环境说得足够详细,所以这里不再赘述,请直接从制作python虚拟环境包Centos换源安装python进行操作,相关依赖最好直接安装好,包括zlib和openssl相关的依赖,前者主要作用在打包压缩,后者主要作用在加密解密。

tips:虽然理论上可以通过python2.6直接装2.7甚至3.x的python,但是由于版本古老,可能(大概率)python2.6下的virtualenv工具无法使用,因为python2.6不支持字典推导式,会报语法错误。尽量使用python2.7以上的版本。

tips2: centos6.x系统使用的是python2.6.6,centos7系统使用的是python2.7.5。

tips3: MacOSX上的/tmp并不是/tmp,而是/private/tmp。

python2.6安装pip,可以直接wget https://bootstrap.pypa.io/2.6/get-pip.py下载get-pip.py文件,然后python get-pip.py来安装

构造一个虚拟环境

在指定的目录创建好完整的python环境了,为什么还需要构造虚拟环境?

以我(浅薄的眼光)看来,安装好的python环境可以通过绝对路径调用,但是很多环境还是会调用系统自身的,这样会造成一种紊乱,我们需要用虚拟环境打包这个完整环境,给它换个皮,创建个单独的空间。

由于那篇博客关于安装虚拟环境说得足够详细,所以这里不再赘述,请直接看制作python虚拟环境包虚拟环境操作进行操作,一般情况下会安装的特别快,如果出现了ImportError: No module named zlib那就是缺少zlib环境。

还记得前文提到的,“虚拟环境中的很多.py文件都只是软连接指向系统自带的python环境对应的.py文件”,此时我们再去看下虚拟环境的lib目录,可以看出虽然有指向,但指向的是之前安装的完整环境,所以理论上可以在任何Linux环境上使用。

打包glibc环境

一般情况下,创建完虚拟环境,就可以直接上传到测试机器,然后激活环境source .venv/bin/activate,然后执行项目入口文件就行了python run.py,如果不出错,那么就可以了,以下的步骤不用看了。

但是我的测试机系统是rhel6.7,会出现一个python: /lib64/libc.so.6: version 'GLIBC_2.14' not found (required by python)错误。

既然是/lib64/libc.so.6下报的错误,那么应该和glibc版本有关系。

通过查找资料,这篇文章解决libc.so.6: version `GLIBC_2.14’ not found问题写得足够详细,原因是系统的glibc版本太低,软件编译时使用了较高版本的glibc引起的,解决方法上面的文章也可以解决,注意将glib安装到之前设置的文件夹下,方便打包。

tips:一般我会将虚拟环境安装在.venv下,而将lib相关的包安装在.lib下

用绝对路径来运行命令

既然glibc也打包了,那么上传到测试机器,如何让python使用高版本的glibc而不使用系统自带的glibc?

直接思路当然是

export LD_LIBRARY_PATH=/YourDir/.lib/glibc-2.14/lib:$LD_LIBRARY_PATH

强制先使用自己制定的glibc,某些时候可以成功,某些时候会报另外一种错,

python: error while loading shared libraries: __vdso_time: invalid mode for dlopen(): Invalid argument

通过查找StackFlow,发现了一个人的遭遇和我一摸一样,Error while using a newer version of glibc,给出的理由是export LD_LIBRARY_PATH覆盖的范围太广了,python不知道该使用哪一个glibc,按照给出的解决方案,测试过了并没有什么用。

之后在知乎找到了调用方法,可见10859 在 glibc < 2.17 的系统上安装 TensorFlow中的调用新版 glibc这一节,直接使用自己打包的glibc去执行指令,这里最好使用绝对路径去执行。

# 这里的GLIBC_DIR指的是glibc安装的位置
$GLIBC_DIR/ld-2.17.so --library-path $GLIBC_DIR:/lib64:$LD_LIBRARY_PATH <command>

# 注意, --library-path后面跟的参数可以更多点,例如$GLIBC_DIR:/lib64:/usr/lib64:$LD_LIBRARY_PATH等等

假设此时执行python会报错, ImportError: cannot import name md5,这是因为–library-path范围不够广,查找下对应的openssl在哪里,添加到–library-path参数就行了。

参考链接:

Search

    Table of Contents