99%的人都会遇到的Python “用户环境”问题
在之前写过一篇关于虚拟环境使用的文章 ,但是还没有好好的介绍一下 Python 的用户环境,原因是自己一直没遇到要使用 用户环境
的使用场景,所以也一直懒得写。
恰巧这两天,自己遇到了一个使用用户环境的体验可以完爆虚拟环境的案例,就拿出来分享一下。
很多人学习python,不知道从何学起。
很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。
很多已经做案例的人,却不知道如何去学习更加高深的知识。
那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!
QQ群:1097524789
1. 我的使用背景
公司有数以万计的服务器,为了对实现对访问记录进行集中管理以及出于安全考虑,每台服务器都有访问限制,必须使用公司的跳板机才能登陆。
每个公司的员工在跳板机上都有自己的用户、 家目录,对于很多需要 root 权限的操作,是高度受限制的。
比如我现在我要在跳板机上实现远程登陆大批量的机器进行一些维护工作,当然我这里使用的还是 Python 来实现,这个 Python 脚本里有一些依赖库(比如之前介绍过的 paramiko 这个神器,对应的文章可以参看:使用 Python 远程登陆服务器的最佳实践),在跳板机上中并没有安装。
做为普通用户的你,是没有权限安装第三方包的。
问题就来了,我如何才能在跳板机中使用 paramiko 这个包呢?
2. 为何不使用虚拟环境?
既然不能对全局的 Python 环境进行更改,那我完全可以自己再创建一个环境,只要这个环境里事先装好 paramiko 这个包不就好了。
因此,使用虚拟环境是一种解决方案,但它并不是一个完美的解决方案。
原因有以下几点:
1、 创建虚拟环境的过程,步骤较多,比较复杂。这里的复杂是相对于我后面要使用的用户环境而言。
2、 虚拟环境是包含一整个 Python 解释器,而且存在大量与系统重复的包,size比较大,并不轻便。
3、 使用 console 模式调试的话,进入很不方便
就算你不使用 console 模式,你调用脚本的方式,也会很奇怪,你得这样
$ zabbix_env/bin/python demo.py
如果你不想使用这样,可以给这个脚本加个可执行权限,并在脚本的第一行指定你的解释器,省去了一点点麻烦,可即便如此,我仍然感觉很别扭。
[wangbm@35ha02 ~]$ cat demo.py
#!/home/wangbm/zabbix_env/bin/python
import zabbix_api
[wangbm@35ha02 ~]$
[wangbm@35ha02 ~]$
[wangbm@35ha02 ~]$ chmod +x demo.py
[wangbm@35ha02 ~]$
[wangbm@35ha02 ~]$ ./demo.py # 可以执行,没有报错
[wangbm@35ha02 ~]$
你可能会问我:为什么不使用 virtualenv + virtualenvwrapper ,这样可以使用 workon 进入虚拟环境。
原因是跳板机里的都是很古老的包,你看上面的 Python 还是 2.7.5 呢,所以你所说的那些工具通通没有。
3. 用户环境原理
这里要介绍的这种方案(用户环境),可能很多人都没有使用过,甚至没有听过,它算是一个冷门但是非常好用的功能。
操作之前 ,先简单介绍一下它。
先提一个问题,Python 在查找导入包时,如果我们多个路径都有这个包,那 Python 如何确定应该从哪个路径进行导入呢?
答案是, 搜索导入路径是有优先级的,你可以通过 sys.path 进行查看(查看更多关于包的细节,可以参看我之前写的文章:全面学习 Python 包:包的构建与分发)
>>> import sys
>>> from pprint import pprint
>>> pprint(sys.path)
['',
'/usr/lib64/python27.zip',
'/usr/lib64/python2.7',
'/usr/lib64/python2.7/plat-linux2',
'/usr/lib64/python2.7/lib-tk',
'/usr/lib64/python2.7/lib-old',
'/usr/lib64/python2.7/lib-dynload',
'/home/wangbm/.local/lib/python2.7/site-packages',
'/usr/lib64/python2.7/site-packages',
'/usr/lib64/python2.7/site-packages/gtk-2.0',
'/usr/lib/python2.7/site-packages',
'/usr/lib/python2.7/site-packages/pip-18.1-py2.7.egg',
'/usr/lib/python2.7/site-packages/lockfile-0.12.2-py2.7.egg']
>>>
可以看到路径 /home/wangbm/.local/lib/python2.7/site-packages
是优先于 /usr/lib64/python2.7/site-packages
路径的。
这就是 用户环境 的原理,只要我们将包装在自己家目录下,就可以优先于全局环境中进行查找。
使用起来,可以做到用户无感知,跟使用原生的全局环境并没有区别。
4. 具体操作方法
创建一个用户环境,并安装上你所需要的包,一条命令就能搞定,这可比虚拟环境简单方便多了。
那么怎么操作呢?
只要你在使用 pip 安装包时,加上 --user
参数,pip 就会将其安装在当前用户的 ~/.local/lib/python2.x/site-packages
下,而其他用户的 python 则不会受影响。
$ pip install --user pkg
这里要注意的是,不能使用这种方式,亲测它会将包装到全局环境下,具体原因我还没有深究。
$ python -m pip install --user pkg
为了让你理解这个过程,我这里来举个例子,并且验证其是否可以做到用户隔离。
# 在全局环境中未安装 requests
[root@localhost ~]$ pip list | grep requests
[root@localhost ~]$ su - wangbm
[root@localhost ~]$
# 由于用户环境继承自全局环境,这里也未安装
[wangbm@localhost ~]$ pip list | grep requests
[wangbm@localhost ~]$ pip install --user requests
[wangbm@localhost ~]$ pip list | grep requests
requests (2.22.0)
[wangbm@localhost ~]$
# 从 Location 属性可发现 requests 只安装在当前用户环境中
[wangbm@localhost ~]$ pip show requests
---
Metadata-Version: 2.1
Name: requests
Version: 2.22.0
Summary: Python HTTP for Humans.
Home-page: http://python-requests.org
Author: Kenneth Reitz
Author-email: me@kennethreitz.org
Installer: pip
License: Apache 2.0
Location: /home/wangbm/.local/lib/python2.7/site-packages
[wangbm@localhost ~]$ exit
logout
# 退出 wangbm 用户,在 root 用户环境中发现 requests 未安装
[root@localhost ~]$ pip list | grep requests
[root@localhost ~]$
有了这个思路,我就可以先在其他机器(前提自己必须拥有管理员权限 )上,创建一个用户环境,并且安装上 paramiko 这个包。
然后将这个用户环境,压缩拷贝至跳板机自己的家目录下的 .local/lib
目录下并解压。
然后直接使用 python 进入 console 模式,现在已经可以直接使用 paramiko 这个包了。
以上就是本次关于用户环境的分享,希望大家以后在遇到这种类似的场景时,可以用得上。
99%的人都会遇到的Python “用户环境”问题的更多相关文章
- 大部分人都会忽略的Python易错点总结
python中复数实现(-2) 0.5和开根号sqrt(-2)的区别** (-2)**0.5和sqrt(-2)是不同的,前者是复数后者是会报错的. print((-2)**0.5) #输出:(8.65 ...
- 99%的Python用户都不知道的f-string隐秘技巧
f-string想必很多Python用户都基础性的使用过,作为Python3.6版本开始引入的特性,通过它我们可以更加方便地向字符串中嵌入自定义内容,但f-string真正蕴含的功能远比大多数用户知道 ...
- Go 语言从新手到大神:每个人都会踩的五十个坑(转)
Go语言是一个简单却蕴含深意的语言.但是,即便号称是最简单的C语言,都能总结出一本<C陷阱与缺陷>,更何况Go语言呢.Go语言中的许多坑其实并不是因为Go自身的问题.一些错误你再别的语言中 ...
- 99% 的人都不知道的 Kubernetes 网络疑难杂症排查方法
原文链接:Kubernetes 网络疑难杂症排查分享 大家好,我是 roc,来自腾讯云容器服务 (TKE) 团队,经常帮助用户解决各种 K8S 的疑难杂症,积累了比较丰富的经验,本文分享几个比较复杂的 ...
- python - 用户交互/数据类型/格式化输出/运算符/流程控制单双多分支
python:用户交互: 等用户输入,做反应: username=input("username:")password=input("password:")pr ...
- python用户评论标签匹配的解决方法
python用户评论标签匹配的解决方法 这篇文章主要为大家详细介绍了python用户评论标签匹配的解决方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 我们观察用户评论发现:属性词往往和情感词伴 ...
- AST抽象语法树——最基础的javascript重点知识,99%的人根本不了解
AST抽象语法树——最基础的javascript重点知识,99%的人根本不了解 javascriptvue-clicommonjswebpackast 阅读约 27 分钟 抽象语法树(AST),是一 ...
- Python用户终端输入
#用户输入,操作 print("python 用户输入操作") # input(提示字符串),函数阻塞程序,并提醒用户输入字符串 instr = input("pleas ...
- python 设置系统/用户环境变量
系统环境变量 winreg.HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment' 用户环境变 ...
随机推荐
- web 安全之页面解析的流程学习
0x00 任务内容: 理解域名解析的整个过程 理解 web 页面请求的整个流程,绘制流程图(nginx 处理的 11 个过程) 学习 http 协议中的字段及含义 学习 http 请求方法以及返回状态 ...
- javascript知识梳理之数据类型
javascript基础知识(在javascript中 = 是赋值符号) 变量 合法的变量命名规则:大小写英文.数字. $ 和 _ 的组合,且不能用数字开头. var a; //声明变量 var s ...
- java 基本语法(十一) 数组(四)数组的常见算法
1.数组的创建与元素赋值: 杨辉三角(二维数组).回形数(二维数组).6个数,1-30之间随机生成且不重复. 杨辉三角 public class YHSJ { public static void m ...
- python并发编程02 /多进程、进程的创建、进程PID、join方法、进程对象属性、守护进程
python并发编程02 /多进程.进程的创建.进程PID.join方法.进程对象属性.守护进程 目录 python并发编程02 /多进程.进程的创建.进程PID.join方法.进程对象属性.守护进程 ...
- css 浮动 定位
浮动 元素的浮动是指设置了浮动属性的元素会脱离标准普通 流的控制,移动到其父元素中指定位置的过程. 语法: float . left . right . none(默认) 注意: 1 ...
- HotSpot的对象模型(5)
Java对象通过Oop来表示.Oop指的是 Ordinary Object Pointer(普通对象指针).在 Java 创建对象实例的时候创建,用于表示对象的实例信息.也就是说,在 Java 应用程 ...
- 第十章:Android消息机制
Android的消息机制主要是指Handler的云心机制,Handler的运行需要底层的MessageQueue和Looper支持. Handler是Android消息机制的上层接口. 通过Handl ...
- GPO - General GPO Settings(1)
Prohibit access to Control Panel and PC settings Disable GPO for Administrators and /or User Groups ...
- 爆肝整理:Linux常用命令,建议收藏!
目录管理命令:mkdir.rmdir mkdir命令 rmdir命令 文件管理命令:cp.mv.rm cp命令 mv命令 rm命令 文件查看命令:cat.tac.head.tail.more.less ...
- Shell基本语法---for语句
for语句 格式 ()for 变量名 in 值1 值2 值3 do 执行动作 done ()for 变量名 in `命令` do 执行动作 done ()for (( 条件 )) do 执行动作 do ...