目录
1.前言
这篇文章是个人理解总结,仅用于个人笔记记录。
2.问题描述
为了安装一个包需要更新在ubuntu上更新python3的版本。ubuntu16默认的python是python2.7和python3.5,但是我安装的包用到matplotlib,需要最低python3.6的版本,所以安装了python3.6,并且按照我前面的笔记 如何升级Ubuntu上的python版本 进行了安装。这里再次强调一定不要卸载ubuntu自带的python,有需要别的版本的话额外安装即可。
由于我安装了python3.6后,把python3的软链接指向了Python3.6,然后之前python3.5用的pip3就出了问了(好像是不能用,具体我忘了),所以后面我就进行了各种修复之路。最后修复成功了,但是我不确定方法是否恰当和正确。故仅作为我的个人笔记。
3.python2和python3
python2和python3是两个大的 python版本,我们安装的都是具体版本,比如python2.7,python3.5等。但是在调用python
或者python3
命令的时候,通常是python
命令对应某个python2的具体版本,比如python2.7;python3
命令对应某个python3的具体版本,比如python3.5。如下图所示,为默认情况下在Ubuntu16.04上的结果:
当然这是一般情况。实际上命令python
或者python3
都是调用了一个软链接,这个软链接指向哪个python版本,那么最后调用的就是哪个python版本。因此通过修改软连接的指向,可以让命令python
对应某个python3的具体版本,而让命令python3
对应某个python2的具体版本。(当然不推荐这样做)
具体操作见 参考1 。
4.pip,pip2和pip3
首先要明确的一点是,每一个python版本,如果安装了pip,都会对应一个这个版本的pip包。比如python2.7对应的是pip2.7,python3.5对应的是pip3.5,python3.6对应的是pip3.6。如果在安装pip包的时候,用的是sudo命令,也就是启动了root用户权限,那么这几个pip文件都在/usr/local/bin
目录下,如图所示:
但是可以看到,这个文件夹下还有pip,pip2和pip3这三个文件,我们在使用pip命令来安装包的时候用的一般都是pip和pip3命令。一般比较常见的说法是pip是python2用的,pip3是python用的。这应该是默认的情况,同时安装了python2和python3,然后又按照命令sudo apt-get install python-pip
安装python2用的pip,和sudo apt-get install python3-pip
安装python3用的pip3。那pip2是啥?
我猜如下:
pip,pip2和pip3应该类似与python,phthon2和python3。也就是说,具体pip、pip2和pip3调用的是哪个版本的python的pip包(如上图中的pip2.7,pip3.5,pip3.6)也是可以改的,只要修改pip、pip2和pip3的文件内容即可。那么pip就是一个总体的名称,代表一种包管理工具。pip2和pip3为了方便记忆和区分,可以指向python2和python3的某个pip包。当然,就好像python、phthon2和python3可以指向任意的具体的python版本一样,pip、pip2和pip3也可以指向具体的python的pip包(如上图中的pip2.7,pip3.5,pip3.6)。然而就像python命令一般指向python2、phthon3命令一般指向python3、而不单独声明python2一样,pip命令保持与python命令的同步,pip2一般也不常用了。
Ubuntu16.04默认安装的python版本是python2.7和python3.5;pip命令(或pip文件)对应的是pip2.7,pip3命令(或pip3文件)对应的是pip3.5;并且pip2.7和pip3.5的版本都是8.1.1。但是我安装python3.6后出现了pip3不能用的情况,所以我又重装了pip3,这就导致pip和pip3都指向了pip3.6。
修改方法:
进入到/usr/local/bin
目录,我们只要修改pip和pip3文件的内容即可。执行命令 sudo gedit pip
或者sudo gedit pip3
进行修改。如果像我的问题那样, 这俩文件内容应该都是:
#!/usr/bin/python3.6
# -*- coding: utf-8 -*-
import re
import sys
from pip._internal.cli.main import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(main())
可以看到第一行的 #!/usr/bin/python3.6
说明这俩命令(pip和pip3)已经都指向了python3.6的pip3.6包,所以导致了上面的情况。
而这两个文件默认的内容应该是(这里有待考证,因为原版的文件由于我安装python3.6的pip已经被修改了,最好找个系统盘进去看一下。这里的文件内容是我参考网上修改,然后解决了pip和pip3的指向问题)
/usr/local/bin/pip
#!/usr/bin/python
# EASY-INSTALL-ENTRY-SCRIPT: 'pip==8.1.1','console_scripts','pip'
__requires__ = 'pip==8.1.1'
import sys
from pkg_resources import load_entry_point
if __name__ == '__main__':
sys.exit(
load_entry_point('pip==8.1.1', 'console_scripts', 'pip')()
)
/usr/local/bin/pip3
#!/usr/bin/python3
# EASY-INSTALL-ENTRY-SCRIPT: 'pip==8.1.1','console_scripts','pip3'
__requires__ = 'pip==8.1.1'
import sys
from pkg_resources import load_entry_point
if __name__ == '__main__':
sys.exit(
load_entry_point('pip==8.1.1', 'console_scripts', 'pip3')()
)
从上面两个文件可以看出,pip的版本都是8.1.1(不论是pip还是pip3,声明版本的语句都是pip==x.x.x)。而pip文件第一行的python,意味着pip文件指向的是python这个软连接指向的python版本的pip包,由于Ubuntu默认python这个软连接指向的是python2.7,所以pip文件指向的应该是pip2.7。pip3文件第一行的python3,意味着pip3文件指向的是python3这个软连接指向的python版本的pip包,由于Ubuntu默认python3这个软连接指向的是python3.5,所以pip3文件指向的应该是pip3.5。这样问题就解决了。
验证:
1.保持/usr/local/bin/pip
和/usr/local/bin/pip3
文件内容如上,验证结果:
2.修改/usr/local/bin/pip
和/usr/local/bin/pip3
的内容,让pip文件和pip3文件的内容互换,那么pip和pip3命令的指向也应该互换。验证结果:
5.使用特定的pip包安装
既然已经知道了pip和pip3本质调用的是某个具体版本的python的pip包(比如pip2.7,pip3.5等),那么想安装到指定的python版本下的包,就可以直接调用这些pip包命令来安装到对应的python版本了。
sudo pip2.7 后面接 list或install
sudo pip3.5 后面接 list或install
或者:
$ python3.5 -m pip 后面接 list或install
$ python3.6 -m pip 后面接 list或install
$ python2.7 -m pip 后面接 list或install
Tips:
-
我的pip还是出了点问题,使用第二种方式的命令报错,第一种方式可用,不过我也不想搞了。参考3 里写的这方面比较多。
-
pip文件不仅存在于
/usr/local/bin/
下,在~/.local/bin/
下也有(隐藏目录,Ctrl+H打开隐藏目录可见),这个文件夹对应的应该是用户目录,安装的时候不用sudo。而前者文件夹下的需要sudo。 -
网上有人说不建议pip命令使用sudo,会导致系统混乱。我也不清楚
-
ubuntu的which、whereis、locate和find命令
which # 只能寻找执行文件 ,并在PATH变量里面寻找。 whereis # 从linux文件数据库(/var/lib/slocate/slocate.db)寻找,所以有可能找到刚刚删除,或者没有发现新建的文件。 locate # 同上,不过文件名是部分匹配。 find # 是直接在硬盘上搜寻,功能强大,但耗硬盘,一般不要用。
6.结语
ubuntu自带的python最好还是不要动,不然都是麻烦。