Python虚拟环境干嘛用的?-Virtual-Env-Tutorial-2024
一、缘起
Pre、
在渗透测试中我们不免的用到很多工具,比如笔者最近下载的OneForAll
,不得不说它真的很受欢迎,在Github
上居然获得了八千个小星星。
网络上的许多工具都使用Python
开发,Python
有不同的版本,并且各个工具总需要依赖一下其他的库和包。
如果你没办法和工具的开发者使用同一版本的Python
环境的话,那么在运行这个脚本时,十有八九你可能会遇到各种各样的报错。而就算解决一百个这样的环境问题,对你的渗透测试能力也并没有太大的帮助。
在我查了一些资料之后,发现有一个虚拟环境的工具可以帮助我们解决这个问题,也就是运行一下虚拟环境的脚本,它可以将你现在的Python
环境变为指定版本。比如OneForAll
就是使用Python3.6.0
开发的,那我们就能把本机的Python3.12.6
的环境变为Python3.6.0
。
听起来是不是很心动,当然这个问题还有其他的解决方案,比如用Pycharm
来切换解释器环境好像也可以。但我不可能每换一台新电脑就都下一个Pycharm
吧,我想要的是一个足够简洁的解决方法,不需要操作很多额外的步骤。
当然,大家如果有更好的解决方案也欢迎提出来!
1、本机环境
本机的环境如下。
Windows11 X64
Python3.12.6
2、目的
使用Virutalenv
在Python3.12.6
的Windows
主机上运行一个Python3.6.0
的虚拟环境,并且能够安装好OneForAll
的所有依赖,正常的运行OneForAll
。
二、虚拟环境的安装
Virtualenv
并不是唯一能够完成这个虚拟环境的功能的,但是本文只讲解它的实现方式,抛砖引玉。
1、Virtual-Env的安装
在已经安装好任意版本Python
环境的主机上使用下面的命令来安装VIrtualenv
。
pip install virtualenv
2、Python3.6.0的安装
在Python
官网下载Python3.6.0
的解释器环境并安装。
Python3.6.0下载地址:Python3.6.0下载地址
安装Python
的具体步骤就不说了(为什么这里不说了呢?因为如果你连Python
都不会装还是先别看怎么用这些脚本了,因为你可能不太会懂...
),只是记得添加环境变量。
三、虚拟环境的配置
1、寻找Python3.6.0的解释器程序
安装好Python
之后我们可以在环境变量中找到其安装位置,从而找到其解释器程序。
当然你也可以在运行窗口输入systempropertiesadvanced
,也可以打开环境变量。
就像这样。
2、创建虚拟环境
这里有一个问题,我发现使用Python3.6
的版本无法创建虚拟环境,而使用Python3.7
的版本才能使用Virutalenv
,这个问题困扰我很久,我没有找到原因。
e:\>virtualenv -p "E:\Program Files\Python\Python36\python368.exe" Python368
RuntimeError: failed to query E:\Program Files\Python\Python36\python368.exe with code 1 err: ' File "E:\\Program Files\\Python312\\Lib\\site-packages\\virtualenv\\discovery\\py_info.py", line 7\n from __future__ import annotations\n ^\nSyntaxError: future feature annotations is not defined\n'
所以我又安装了Python3.7.9
的解释器环境,并且使用这个命令来创建虚拟环境。
virtualenv -p "C:\Users\辣椒\AppData\Local\Programs\Python\Python37\python379.exe" "e:\Python379" # virtualenv -p 解释器执行程序 虚拟环境文件目录名称
由于我的主机上有多个Python
解释器,并且我修改了不同Python
解释器的名称。例如Python3.12.6
我改为Python3126
,所以我的命令稍长一点,需要指定使用哪个Python
解释器来运行Virtualenv
。
python3126 -m virtualenv -p "C:\Users\辣椒\AppData\Local\Programs\Python\Python37\python379.exe" Python379
这样ok
了。
e:\>python3126 -m virtualenv -p "C:\Users\辣椒\AppData\Local\Programs\Python\Python37\python379.exe" Python379
created virtual environment CPython3.7.9.final.0-64 in 794ms
creator CPython3Windows(dest=E:\Python379, clear=False, no_vcs_ignore=False, global=False)
seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=C:\Users\辣椒\AppData\Local\pypa\virtualenv)
added seed packages: pip==24.3.1, setuptools==75.2.0, wheel==0.44.0
activators BashActivator,BatchActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator
进入虚拟环境的目录中的Script
文件夹,打开Cmd
环境,执行脚本activate.bat
,就可以成功使用一个干净的3.7.9
环境了。
这个虚拟环境只存在于当前的命令行环境中。
四、使用启动的虚拟环境安装OneforAll
1、一个失败的小试牛刀
首先看看我的OneForAll
的文件存放位置,这里有一个requirements
的文件,里面记录了这个脚本运行所需要的一些依赖项。
切换到OneForAll
的目录环境下。
使用下面的命令安装该依赖,再次提醒,我这里的命令使用Python379
是因为我自己把Python
解释器程序的名称修改了才需要这样做。
python379 -m pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
如果你没有修改Python
解释器的名称,只需要这样即可。
pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
在这里遇到了一个问题,也就是我的3.7.9
环境仍然没有办法完全的安装好OneForAll
所使用的依赖,根据提示,我们需要使用3.8
的环境来运行。
那么只好这样,重新安装一个3.8
的Python
,并且启用其虚拟环境。
2、再来!!!
同样的命令,同样的敲..
C:\Users\辣椒>python3126 -m virtualenv -p "C:\Users\辣椒\AppData\Local\Programs\Python\Python38\python380.exe" Pyenv380
created virtual environment CPython3.8.0.final.0-64 in 1393ms
creator CPython3Windows(dest=C:\Users\辣椒\Pyenv380, clear=False, no_vcs_ignore=False, global=False)
seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=C:\Users\辣椒\AppData\Local\pypa\virtualenv)
added seed packages: pip==24.3.1, setuptools==75.2.0, wheel==0.44.0
activators BashActivator,BatchActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator
好好好,不出意外又报错了,这次提示要3.10
的Python
版本。
3、再再来!!
哈哈,我疯了,如果再不好的话。
C:\Users\辣椒\AppData\Local\Programs\Python\Python310>python3126 -m virtualenv -p "C:\Users\辣椒\AppData\Local\Programs\Python\Python310\python3109.exe" Pyenv3109
created virtual environment CPython3.10.9.final.0-64 in 5170ms
creator CPython3Windows(dest=C:\Users\辣椒\AppData\Local\Programs\Python\Python310\Pyenv3109, clear=False, no_vcs_ignore=False, global=False)
seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=C:\Users\辣椒\AppData\Local\pypa\virtualenv)
added seed packages: pip==24.3.1, setuptools==75.2.0, wheel==0.44.0
activators BashActivator,BatchActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator
命令还是这样,记得是切换到OneForAll
下的目录执行的,因为Requirement
文件在OneForAll
的文件夹中。
python3109 -m pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
总该成功了吧..
大家可能会问为什么不用3.12.6
的环境直接装呢?因为我试过了,3.12.6
的Python
环境装不了,有问题,所以才出此下策...
好的,经过漫长的等待,我终于使用Python3.10.9
的环境获得了我使用Python3.12.6
环境安装OneForAll
时得到的同样的依赖错误...
ModuleNotFoundError: No module named 'tenacity'
于是我放弃了挣扎,开始手动一个个安装这些依赖,每安装好一个又会提示另外一个依赖的缺失,我开始意识到是不是作者没有把这些依赖在Requirement
中写全。或者只是我的环境简单的有问题罢了?
在我大概安装了七八个依赖之后,OneForAll
终于得以运行...
4、终于!
终于得以运行了,附上一张截图吧。
五、总结
1、过程梳理
今天我们的目标是使用Virtualenv
创建OneForAll
作者所说的Python3.6.0
虚拟环境,并且使用这个虚拟环境安装OneForAll
所需要的库,以此来和我本机的Python3.12.6
所安装的包隔离开来。希望这样能够让OneForAll
正常运行。
但是在实践过程中发现旧版的Python
在包安装方面已经不支持作者的Requirement
文件中提供的某些包的版本,例如numppy2.1.2
需要Python3.8
版本,还有一些包需要Python3.10
的版本才能够运行。
这可能是因为作者没有及时更新ReadMe
文件导致的。
于是在切换到Python3.10.9
的版本之后我仍然需要手动安装一些依赖才能够运行OneForAll
的脚本程序。
2、学习到的知识
1.
根据这次的经验,下载再安装类似的脚本文件我可能会先尝试手动安装依赖,如果能够解决问题,那也不需要搞这么多麻烦事了。
2.
安装前可以多看看Github
项目上的Issue
来参考别人安装中出现的问题。
3.
能够使用VirtualEnv
创建Python
的虚拟环境,到现在为止,我的电脑上已经可以运行Python3.6
,3.7
,3.8
,3.10
,3.12
不同版本的环境了,可能以后会用到。
3、知识梳理
以往我总喜欢把文章写成像一篇教程那样,这意味着我在文章的一开头就应该准确无误的讲出我对这个知识点的理解,可是通常来说。
随着我在实践过程中查阅资料,这很可能让我意识到原来的理解是错误的,于是我会删除之前说的话,然后重写。
但这样子关于我为什么犯错,为什么产生这个错误的想法的过程,就没有被记录了,而分析这个思路,对提升自己的方法论也是重要的。
所以之后,我都会在文章的最后再写一个小节,来重新总结这些知识。
(一)、为什么需要VirtualEnv
(1)、解决不同项目需要使用不同版本依赖的问题
假设现在有项目A
和项目B
,A
程序依赖的是ddddocr
库的1.0
版本,而B
程序依赖的是ddddocr
库的2.0
版本,并且dddd
库的1.0
和2.0
版本的语法不同。
而一个Python
环境中只能安装一个版本,无论我们安装哪一个版本,都会导致另外一个程序无法运行。
使用VirtualEnv
,能够为每个项目创建一个独立的空间,各自项目的包依赖不会受到干扰。
(2)、解决不同Python解释器环境切换的问题(错误想法)
写到这里我发现这并不是需要VirtualEnv
才能够解决的,假设我在主机上分别安装了3.6
,3.7
,3.8
这些环境,我只需要将它们的名字命名为不同的就可以使用不同版本的Python
解释器来运行,这并不会给环境带来冲突。
并且不同版本的Python
解释器中的包管理也是不冲突的。VIrtualEnv
的目的是为了给使用相同解释器环境的项目提供一个新的包管理空间。
(二)、什么是VirtualEnv
VirtualEnv
从Python3.3
开始存放在Venv
标准库中,它用于创建一个独立的Python
虚拟环境。
(三)、如何使用VirtualEnv
安装。
pip install virtualenv
指定某一个Python
解释器和指定目录并创建虚拟环境。
virtualenv -p "C:\Users\辣椒\AppData\Local\Programs\Python\Python37\python379.exe" "e:\Python379" # virtualenv -p 解释器执行程序 虚拟环境文件目录名称
为了演示我使用下面命令创建一个Python3.12.6
环境的虚拟环境,不使用-p
指定解释器的话即为当前Python
解释器。
python3126 -m virtualenv Pyenv3126
启动虚拟环境。
进入到虚拟环境目录中的Scripts
文件夹,并且在此打开cmd
命令行窗口,执行activate.bat
脚本。
判断是否进入虚拟环境你可以使用pip
list
来查看该环境下安装了哪些包,如果你是新创建的,那这个包依赖应该很干净。
但是此时我发现了一个恐怖的问题,就是我的虚拟环境好像根本没有起作用,我启用了虚拟环境和没有启用时,其pip
列表中的包是一样的。
我意识到哪里出了错,我发现因为我把各个版本的Python
解释器都修改了名称,成为诸如Python380
,Python3126
之类的,而虽然我在创建时指定了Python
解释器,可Virtualenv
却没有识别。
这个问题在我使用Venv
来创建虚拟环境时得到了解决。
使用Venv
创建虚拟环境的命令如下。
python3126 -m venv Pyenv3126 # python3126 -m venv 虚拟环境的文件夹名称
退出Virtualenv
也很简单,执行Scripts
文件夹中的deactivate
脚本即可。
4、做的错犯
1.
没有验证某个功能的真实性就想当然的以为是那样,花了一天多,如果不是最后验证Virtualenv
并不能成功创建虚拟环境可能以后还是人云亦云。
2.
尝试在解决问题时先研究当前的问题是不是真的很难解决,然后再换方法,一不行就换容易导致今天的问题,就是到头来还是要解决原来的问题。
5、方法论总结
1.
做完所有验证再下结论。
2.
解决问题要有耐心。