Python3.6 pip install vs sudo pip install

Ubuntu 18.04 Linux學習心得

Gopher is cute
Caesar's study review on Web development
12 min readMay 23, 2018

--

我想轉職成為web開發者,先前在微軟win10的環境學習Python與Git,時常遇到編碼及換行CRLF的問題,於是有了學習Linux的心情,想深入軟體開發領域,我認為不能死守在自己最熟悉的微軟環境。

使用Virtual Box安裝了Ubuntu 18.04,學習Linux的目錄結構 (Filesystem Hierarchy Standard,FHS),了解Linux的權限問題以及環境變數$PATH、$HOME的作用。

(此篇心得為個人領悟,若有錯誤請告知)

利用pipe | (I/O Redirection)結合ls指令與grep指令,查詢Ubuntu原生系統的執行檔/usr/bin及函數庫/usr/lib,存在哪些Python函數庫。

從上圖可得知,Ubuntu 18.04原生系統存在著Python3.6及Python2.7的函數庫,有了函數庫,執行檔才可以作用。

而Python3與3.7其實並非主要函數庫,實際查看相關目錄就可以發現,裡面只存在輔助性質的檔案,python主要運作還是依靠Python3.6及Python2.7。

/usr/bin所找到的檔案也就是所謂的二進位檔案,在Bash中我們打的指令都必須存在於/bin的相關目錄,才可以使用。

舉例來說,/usr/bin可以看到有python3、python3.6、python3.6m...等等,打指令python3時會導向到python3.6,若你打指令python2或python系統會告訴你找不到相關command。

即使你有python2.7的函數庫,但只要執行檔沒有,就無法利用。

藉由安裝python的套件管理工具pip,讓我更了解Linux的基本運作過程,首先安裝pip,在Bash中打指令;

由於Linux原生就有安裝Python3.6及Python2.7,Python3以上的版本請安裝 python3-pip 其工具為 pip3 ,而Python2.7的版本請安裝 python-pip 其工具為 pip。

apt-get是 ubuntu官方的套件管理工具,由apt-get所安裝的套件其預設目錄為/usr/bin,安裝pip3後,可利用whereis 指令查詢,其所在的目錄。

/usr/bin/ 在Linux的目錄下,其權限屬於root,一般使用者帳號無法對該目錄做檔案刪除或是寫入,於是需要加上指令 sudo ,以root的身分進行安裝。

若你為一般使用者帳號不加上指令 sudo,直接使用apt-get,只會得到不符權限的訊息,因為apt-get試圖對root權限的目錄做讀寫,而你現在的身分只是一般帳號,在Linux中,權限是很重要的且必須了解的基本觀念。

若是對於Linux的目錄結構有興趣了解,可參考以下連結

pip與apt-get類似,一樣是套件管理工具,只不過pip是屬於第三方管理工具,專門安裝與python有關的套件,而apt-get是官方的套件管理工具,藉由第三方軟體所安裝的套件,其預設目錄為可分為兩種;

  1. 系統端( /usr/local/)
  2. 用戶端(/home/<username>/.local/)

假設我們現在要透過pip3安裝jupyter notebook,若希望安裝在系統端則要打指的指令如下,且其安裝目錄為 /usr/local/lib/

所謂裝設在系統端的意思是說,若該台電腦還有其他使用者,所有的使用者都可以使用系統端安裝的套件,但是通常不建議這麼做,由於root權限是最高級的,透過第三方管理工具安裝的套件,可能會有資安上的疑慮,因此通常建議將第三方套件裝在用戶端。

至於 -H 的參數是什麼意思,這就牽涉到環境變數$HOME的問題,$HOME儲存了使用者的家目錄路徑,也就是說$HOME=/home/<username>/,首先要了解pip在安裝套件時,會讀取$HOME環境變數,得到家目錄的路徑後,在家目錄底下創造/.cache/pip/來進行緩衝下載的動作。

若你打指令為 sudo pip3 install jupyter 那系統會提出警告,但不會影響套件安裝,不過安裝套件的速度可能會慢了一點?

這個警告訊息意思是說,由於使用了sudo指令,你現在的身分暫時為root,但是$HOME依舊是家目錄的路徑,你的身分為Root而家目錄的owner為一般使用者,雖然root有足夠的權限對一般使用者的目錄進行讀寫,但是系統不想在家目錄底下建立一個root權限的/.cache/目錄。

家目錄底下應該權限只能有一般權限,若是出現一個root權限的目錄,往後若有其程式需要讀取該目錄,則會被禁止訪問,為了避免此情況以及統一家目錄權限為一般權限,因此這個警告說明了,此次安裝不使用緩衝下載的模式(the cache has been disabled)。

回到-H,若使用指令sudo 加上參數-H,則會改變環境變數$HOME的值,將$HOME的值從家目錄的路徑改為/root目錄,如此就可以使用緩衝下載的功能,又不會影響家目錄的權限完整性,可由以下例子簡單說明sudo -H的功能

其他相關討論可以參考 stackoverflow

也可能是ubuntu本身的BUG?

談完了系統端的安裝,再來談談若是希望安裝jupyter notebook在用戶端則要打指的指令如下,且其安裝目錄為/home/<username>/.local/lib/

指令1跟2,我在Ubuntu實測並沒有查詢到差異處,猜測對Mac的用戶才有區別,在用戶端安裝的套件只有該使用者可以使用,別的使用者無法使用。

一開始我安裝第一個第三方套件在用戶端時,我一直以為安裝失敗,因為系統一直找不到jupyter的指令,前面有說過要使用指令,必須在/usr/bin或/usr/local/bin或/home/<username>/.local/bin/有相關檔案才可以使用,之後才發現是環境變數$PATH的問題。

環境變數$PATH,儲存了許多路徑,作業系統會讀取$PATH的值,依序讀取路徑查詢執行檔,簡單來說$PATH代表著「系統要到哪些路徑底下找執行檔」。這樣講可能太過抽象,以下舉例

上述例子可知$PATH儲存了10個路徑,每個路徑以冒號:分隔,假設現在我想要執行jupyter指令,系統會根據$PATH首先尋找/home/caesar/.local/bin,若在該路徑沒有發現jupyter的bin檔,接下來會尋找/usr/local/sbin,依此類推直到搜尋所有$PATH儲存的路徑,若所有路徑都搜尋完,依舊沒有在這些路徑發現jupyter的bin檔,系統就會提示Command ‘jupyter’ not found

仔細觀察可以發現,$PATH儲存的路徑從最前面開始,依序為用戶端,之後才是系統端,也就是說系統會優先讀取用戶端的資料,若在用戶端就讀取到相關檔案後,系統則停止讀取$PATH的路徑,藉此打造個人化的設定及安裝環境。

那麼$PATH路徑的資料是從哪邊讀取或擴增的呢?這就要提到bash 的環境設定檔, bash 在啟動時直接讀取這些設定檔, 其中又可以分為系統端及用戶端的設定檔。

介紹 bash 的設定檔前,我們要先知道的就是 login shell 與 non-login shell! 重點在於有沒有登入 (login) !詳細介紹請參考鳥哥的私房菜。

login shell 讀取這兩個設定檔

  1. /etc/profile:這是系統整體的設定,最好不要修改這個檔案
  2. ~/.profile 或~/.bash_login或~/.bash_profile :屬於用戶端的設定

bash 在讀完系統端 /etc/profile的設定,並藉此呼叫其他設定檔後,接下來是會讀取用戶端的設定檔。我的ubuntu 18.04中,bash用戶端的設定檔為~/.profile,部分內容如下

簡單說明以下內容,指令 -d: 該『檔名』是否存在且為目錄,若存在該目錄則執行以下動作PATH=”$HOME/bin:$PATH”,此動作為擴增環境變數$PATH。

而non-login shell 僅會讀取

  1. ~/.bashrc :規範了較為保險的命令別名
bash設定檔讀取流程

回到一開始所說,安裝第一個第三方套件在用戶端時,一直找不到jupyter的指令。這是因為login shell登入時,$HOME/.local/bin的目錄還不存在,因此$PATH不會擴增此路徑($HOME/.local/bin)。

直到安裝第一個第三方套件在用戶端時,~/.local/bin的目錄才生成,此時的$PATH並沒有加入~/.local/bin,故執行jupyter指令系統才會說找不到該指令,解決的辦法為重新登入一次,讓bash重新套用login shell設定,就可以正常執行jupyter的指令了,或者選擇export PATH也可以。

此情況只會發生在第一次安裝第三方套件在用戶端,之後由於目錄生成了,往後$PATH就會依照bash的設定擴增此路徑,但對於剛學習Linux的我,一開始一直以為自己安裝失敗,看了很多Linux的資料才明白發生此錯誤的原因。

以上為我學習Linux的心得,老實說覺得自己似乎有點太鑽牛角尖,感覺對於學習WEB開發並無太多幫助,可能以後架node.js環境比較清楚自己在做什麼吧?我又不是要當devops 也沒有想搞維運,但個性上就是想把基本的東西搞清楚。

恰巧最近在公司寫C程式用到了multi-thread的概念,學習Linux時有看到工作管理 (job control)的資料,藉由操作指令 jobs、將背景工作拿到前景來處理:fg、將指令丟到背景中『執行』的 &,學到一些 Process概念,讓我在學習multi-thread時更加明白程式想表達的意思,multi-thread似乎是作業系統的基本觀念,看來日後也是要補起作業系統這門學科。

之後心力會放在資料結構以及Javascript,報名了appwork school的前端課程,還沒收到面試通知,擔心著是否我的努力還不足,連面試資格都不能獲取,非本科真的好多東西要學,很希望可以藉由appwork school加速腳步。

--

--

Gopher is cute
Caesar's study review on Web development

我的第一份後端工作結束了,短短四個月,部門全員掰掰,尋找新的機會。