问题整体思路
- 问题描述
- 服务器上有多个Python版本,在以用户NH连接,并以源码方式编译安装并配置环境变量后,执行命令python,发现python版本并不是自己所安装的
- 问题关键点
- 分析源码安装Python的各个步骤,确定问题是出在环境变量的配置上
- Linux Python多版本分为两种情况,
- 一类是通过apt、yum等包管理根据直接安装的,这类命令不需要配置环境变量
- 第二类是通过源码安装,需要配置环境变量
- 尝试
- Linux是通过环境变量
$PATH
去查找命令所在位置的,所以通过echo $PATH
查看PATH这个环境变量的值。发现PATH中是有指定的值的 - 通过
which -a python
查看可以从哪些目录寻找到python。发现which是可以找到自己指定的python目录的 - 另外了解了interactive shell、login shell和none、none,目的是为了了解环境变量各个配置文件的加载顺序。但了解了‘配置文件加载顺序’之后仍然不能解决。
- 问题转到
$PATH
这个具体的环境变量上
- Linux是通过环境变量
- 最终解决
- 之前配置的是
PATH=$PATH:%PythonHome%/bin
,调整为PATH=%PythonHome%/bin:$PATH
解决
- 之前配置的是
- 结论
- Bash和编程语言不同,编程语言中的变量会以最后一次赋值作为最终值,
- 当Linux的PATH环境变量指定的多个目录中都有python这个命令,会根据 ‘靠前的目录’ 找到这个命令
- 经验
- 意识到了conda等类似环境管理的重要性,在麻烦开始之前,做好环境管理
相关知识点
在尝试解决问题时,考虑到了Bash环境变量的问题,一般我们配置环境变量是在/etc/profile
中,可能还会遇到在 ~/.bashrc
、/etc/profile.d
中配置环境变量,
很直接地产生了一些疑问,在这么多文件中配置最终会采用哪些文件的配置?
其实通过查看这些文件的完整代码就会看到,他们是调用和被调用的关系,也就是从一个文件中读取一些配置后,会从其它文件接着读取。
在Bash的官方doc中,第6.2节介绍的Startup Files,其中详细介绍了上述文件的执行顺序,并介绍了bash在不同的调用方式下,哪些Startup Files会发挥作用
如果是以interactive login shell
和non-interactive shell with the --login option
调用的bash,如果/etc/profile
存在,Bash就会读取该文件。Bash读取这个文件之后,这个文件会以~/.bash_profile, ~/.bash_login, and ~/.profile这个顺序来寻找这些文件(这些文件不一定都存在), 并从它们其中的第一个存在且可读中读取并执行命令。
如果是以interactive shell that is not a login shell
启动,则会执行~/.bashrc
。
(更多细节可以查看原文档)
为什么要划分出那么多文件?
个人理解是为了解决环境变量的冲突。
上一个问题是具体的实现,与上一个问题对比,这个问题是更高层次的设计。换句话来说,Bash的设计者应该是为了解决环境变量的冲突问题,才设计出了这么多文件以及它们之间的调用顺序。
Source
在配置环境变量时,会使用source 配置文件
命令让相应的配置文件立即生效,有的文章可能会将source称之为刷新。
但实际上每个配置文件都是一个shell脚本,source的实际作用是让脚本在当前进程中执行。这里的相关知识点是Linux进程。