實(shí)驗(yàn)室服務(wù)器使用的系統(tǒng)為 Ubuntu 16.04怖侦,自帶的 python 版本為 Python 2.7.12 和 Python 3.5.2爽航,命令行下使用$ python
命令來(lái)啟動(dòng) python 時(shí)默認(rèn)是 python2.7沮翔。而我想使用 Python 3.8秋度,因此嘗試從源碼安裝 Python届氢,并更改默認(rèn)的$ python
命令指向促脉。
注:如果想要安裝某個(gè)非系統(tǒng)自帶的 Python 版本,切忌沖動(dòng)刪除系統(tǒng)自帶的 Python 2.7 和 Python 3.5代芜,某些系統(tǒng)應(yīng)用可能依賴于這些 Python 環(huán)境的調(diào)用,防止系統(tǒng)出錯(cuò)浓利!
1. 官網(wǎng)下載 python 源碼
在官網(wǎng)這里下載你想要的 linux 環(huán)境下的 python 源碼挤庇,如我下載的是下圖第一個(gè) Gzipped source tarball,其實(shí)二選一就好贷掖。
我下載完成后是一個(gè)叫 Python-3.8.3.tgz 的文件嫡秕,在下載目錄里使用tar -xvf Python-3.8.3.tgz
命令解壓文件包,目錄里多出一個(gè) Python-3.8.3 的文件夾苹威,cd 命令進(jìn)入該文件夾昆咽。
上述操作總結(jié)起來(lái)如下:
wget https://www.python.org/ftp/python/3.8.3/Python-3.8.3.tgz
tar -xvf Python-3.8.3.tgz
cd Python-3.8.3
2. 安裝依賴
Python 源碼編譯、安裝過(guò)程中需要用到一些工具牙甫,你的系統(tǒng)里可能有掷酗、可能沒(méi)有這些工具,保險(xiǎn)起見(jiàn)窟哺,使下以下命令先把這些依賴安裝好吧泻轰。
這一步其實(shí)可以放在最開始執(zhí)行。
- Ubuntu/Debian 系列:
sudo apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev libffi-dev liblzma-dev python-openssl
- Fedora/CentOS/RHEL 等可參考:
sudo yum install zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel xz xz-devel libffi-devel
3. 編譯并安裝 python
注意根據(jù)第 1 節(jié)最后的 cd 命令且轨,我們現(xiàn)在是在 python 的源碼文件夾里進(jìn)行操作浮声。
3.1 指定 python 的安裝目錄
作為 CS 小白,我還是要區(qū)別一下 python 的“源碼目錄”和“安裝目錄”兩個(gè)概念的旋奢,畢竟是第一次在 linux 下從源碼安裝軟件泳挥。
要知道,當(dāng)前我們所在的目錄Python-3.8.3
是由最開始下載的源碼壓縮包解壓出來(lái)的至朗,因此這個(gè)目錄里是 python 這個(gè)軟件開源的源碼屉符,故稱之為源碼目錄;而安裝目錄是說(shuō)我們這個(gè) python 軟件要安裝在系統(tǒng)的哪個(gè)地方爽丹,你啟動(dòng) python 的時(shí)候?qū)嶋H是從這里啟動(dòng)的筑煮。
類比下 windows 的話就是:源碼目錄是你下載的那個(gè)安裝程序xxx.exe
所在的目錄,還記得一些大型軟件(如 office 2016)安裝的時(shí)候通常是一個(gè)文件夾里有一個(gè)setup.exe
的程序嗎(當(dāng)然粤蝎,很多軟件你下載下來(lái)的安裝包其實(shí)就一個(gè)單獨(dú)的.exe 可執(zhí)行文件就沒(méi)了)真仲,windows 下就是直接點(diǎn)擊這個(gè)xxx.exe
進(jìn)行安裝的,這就是所謂的源碼目錄初澎;那么顯而易見(jiàn)秸应,安裝目錄就是你在運(yùn)行xxx.exe
進(jìn)行安裝的時(shí)候選擇的安裝地址虑凛,譬如說(shuō)經(jīng)常是C:\Program Files\
等等。真正的軟件組件肯定是在安裝目錄里软啼,軟件需要從這里啟動(dòng)桑谍,而你平常習(xí)慣的在 windows 桌面/開始菜單里點(diǎn)擊的圖標(biāo)就是從安裝目錄里延伸出的快捷方式。
回歸主題祸挪,我選擇的 python 安裝目錄是/opt/python3.8
锣披,因此通過(guò)如下命令先建立這個(gè)文件夾:
mkdir /opt/python3.8
3.2 執(zhí)行./configure
python 源碼目錄里有一個(gè) configure 可執(zhí)行文件,這個(gè)命令的作用是生成一個(gè) MakeFile 文件贿条,此 Makefile 文件用來(lái)被之后的 make 命令所使用進(jìn)行源碼編譯(Linux 需要按照 Makefile 所指定的順序來(lái)編譯 (build) 程序組件)雹仿。
configure 通常有一些參數(shù)選項(xiàng),最常見(jiàn)的是--prefix整以,用來(lái)指定安裝目錄胧辽。此外,要注意的是公黑,python3.4 以后自帶了 pip邑商,為了在之后能夠成功使用這個(gè) pip 進(jìn)行 python 庫(kù)的安裝,最好加上--with-ssl 參數(shù)凡蚜。--with-ssl 這個(gè)參數(shù)不加的話 python 的安裝過(guò)程不受影響人断,只是當(dāng)你想要用 pip 安裝 python 庫(kù)的時(shí)候會(huì)報(bào)錯(cuò),發(fā)現(xiàn)它無(wú)法連接到 pypi番刊,跟 pip 連不上網(wǎng)沒(méi)啥區(qū)別含鳞。
總之,使用如下命令:
./configure --with-ssl --prefix=/opt/python3.8
3.3 make 編譯
make
命令實(shí)際就是編譯源代碼芹务,其根據(jù) Makefile 文件執(zhí)行編譯指令并生成可執(zhí)行文件蝉绷。
make
3.4 使用 make install 進(jìn)行安裝
當(dāng) make 的源代碼編譯無(wú)誤,使用make install
就是進(jìn)行軟件的安裝枣抱,似乎也要根據(jù) Makefile 文件以及根據(jù) make 生成的可執(zhí)行文件進(jìn)行執(zhí)行熔吗,原理尚不明確,現(xiàn)在確定的是其現(xiàn)實(shí)意義是把軟件安裝到configure
命令指定的目錄佳晶,對(duì)我而言就是/opt/python3.8
桅狠。
make install
因?yàn)槭擒浖惭b,因此通常需要 sudo 權(quán)限轿秧。
sudo make install
4. 配置環(huán)境
至此 python 的安裝過(guò)程其實(shí)已經(jīng)完成中跌,在安裝目錄里使用./bin/python3
即可打開安裝好的 python 可執(zhí)行文件并進(jìn)入 python 命令行了:
但是每次要從安裝目錄里啟動(dòng) python 很不方便,我們想要達(dá)到的是在 shell 中隨時(shí)隨地喚醒這個(gè) python菇篡,這便需要進(jìn)行相關(guān)的環(huán)境配置漩符。
4.1 刪除原有的軟鏈接
開頭的時(shí)候提到,我的系統(tǒng)中默認(rèn)的 python 命令打開的是系統(tǒng)自帶的 python2.7驱还,現(xiàn)在要更改這個(gè)命令讓它打開的是新安裝的 python3.8嗜暴,這需要我們先理解命令行(shell)中的命令是怎么執(zhí)行的:
- 在 shell 中凸克,執(zhí)行的所有命令如 cd、ls闷沥、ps萎战、python 等,分為“內(nèi)建命令”和“外部命令”舆逃。內(nèi)建命令是 shell 自帶的命令蚂维,好比編程語(yǔ)言不需要使用函數(shù)庫(kù)而自帶的那些函數(shù),如
print()
函數(shù)路狮;外部命令是為了豐富 shell 的功能而自己安裝的一些命令鸟雏,好比你編程時(shí)使用的第三方庫(kù),當(dāng)然览祖,有些外部命令是你安裝 linux 系統(tǒng)時(shí)就已經(jīng)自帶的命令,好比編程語(yǔ)言的標(biāo)準(zhǔn)庫(kù)炊琉,雖然是“自帶的”但依然是“外部命令”展蒂。 - python 毫無(wú)疑問(wèn)是外部命令,那么外部命令是怎么執(zhí)行呢苔咪?這就要提到平常經(jīng)常見(jiàn)到的
PATH
概念了锰悼。當(dāng) shell 中輸入一個(gè)命令時(shí),shell 首先檢驗(yàn)它是不是內(nèi)建命令团赏,當(dāng)內(nèi)建命令中找不到這條命令時(shí)箕般,shell 就搜索你的PATH
,這個(gè)東西就是一個(gè)存儲(chǔ)了你的外部命令所在路徑的集合舔清,shell 在這些路徑中尋找你輸入的命令對(duì)應(yīng)的那個(gè)可執(zhí)行文件丝里,找得到就在 shell 中執(zhí)行,找不到就報(bào)錯(cuò)体谒。 - 于是杯聚,shell 中 python 命令的執(zhí)行過(guò)程為:在
PATH
存儲(chǔ)的那么路徑里(包含很多路徑,其中一個(gè)是/usr/bin/
)尋找一個(gè)名為python
的可執(zhí)行文件抒痒,一般情況下幌绍,有這么一個(gè)文件:/usr/bin/python
,找到它以后執(zhí)行故响,就打開了 python傀广。
現(xiàn)在我們使用ls -l /usr/bin/python
查看這個(gè)文件的詳細(xì)信息,發(fā)現(xiàn)它是一個(gè)執(zhí)行 python2.7 的軟鏈接(相當(dāng)于 windows 里的快捷方式)彩届,把它刪掉伪冰,這樣在 shell 中直接輸入 python 就再也打不開任何 python 環(huán)境了,它成了一個(gè)無(wú)效命令惨缆。
總結(jié)一下糜值,這步操作的命令過(guò)程為:
ls -l /usr/bin/python
sudo rm /usr/bin/python
4.2 建立新的軟鏈接
使用軟鏈接創(chuàng)建命令ln -s
把新安裝的 python 鏈接到上步刪除的舊的軟鏈接所在目錄即可丰捷。即:
ln -s /opt/python3.8/bin/python3 /usr/bin/python
此時(shí)在任意工作目錄的 shell 中任意輸入 python,即可打開新安裝的 python 3.8 了寂汇。
chuan@workstation:~$ python
Python 3.8.3 (default, Jun 21 2020, 16:34:59)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
4.3 配置 pip 命令
你的系統(tǒng)可能也自帶了 pip 或 pip2病往、pip3 等命令,由于自帶的 pip 關(guān)聯(lián)的肯定是原有的 python 環(huán)境骄瓣,此時(shí)盲目使用 pip install 一些庫(kù)的話停巷,這些庫(kù)其實(shí)被安裝到了系統(tǒng)自帶的 python 環(huán)境里了,在你新安裝的 python3.8 里根本無(wú)法導(dǎo)入這些庫(kù)榕栏,這就尷尬了畔勤。
這個(gè) pip 其實(shí)和之前被刪除的 python 軟鏈接一樣,是一個(gè)在相同目錄下的 pip 軟鏈接扒磁,和更改 python 命令一樣庆揪,刪除掉原來(lái)的 pip 被建立一個(gè)新的 pip 軟鏈接即可。為了讓 pip 關(guān)聯(lián)的是新下載的 python3.8妨托,新的 pip 應(yīng)該來(lái)自 python3.8 自帶的那個(gè) pip缸榛,其路徑為./opt/python3.8/bin/pip3
。話不多說(shuō)兰伤,代碼如下:
sudo rm /usr/bin/pip
ln -s /opt/python3.8/bin/pip3 /usr/bin/pip
5. 前方告捷内颗,嘿嘿
6. 附記
新安裝的 pip 在安裝第三方庫(kù)時(shí)還是有一個(gè)小小的報(bào)錯(cuò),提示什么文件夾權(quán)限不明確/不足以及:
Could not install packages due to an EnvironmentError: [Errno 13] Permission denied
根據(jù)百度敦腔,出現(xiàn)這個(gè)報(bào)錯(cuò)之后均澳,在 pip install 之后加個(gè)--user 可解決,如下:
pip install --user numpy
第一次加過(guò)--user 之后便不再有報(bào)錯(cuò)符衔,但不明所以的是這樣之后 pip 安裝的第三方庫(kù)的目錄被定在了~/.local/
找前,原來(lái)似乎不存在這個(gè)文件夾。不過(guò)這并沒(méi)有造成后續(xù)什么問(wèn)題判族,暫且不管了纸厉,挖個(gè)坑后續(xù)再研究。
另外五嫂,不知道能不能選擇直接把一個(gè)已安裝的 pip 綁定到指定的 python 環(huán)境颗品,而不用這么折騰,未完待續(xù)吧......