Linux 的軟件管理 - 安裝、卸載、升級 和 依賴管理
1. 對比:Windows 和 Linux 上軟件的安裝與卸載
就像在 Windows 下,很多軟件也有安裝版與免安裝版一樣,在 Linux 下也有這樣的差別。
Windows 下的安裝版軟件在安裝時需要管理員權限,它會在系統的註冊表中添加關於自己的信息,也可能會在系統的某些某些地方添加一些文件。一般而言,這樣的軟件都會在安裝目錄下提供一個名為uninstall.exe
的文件,它會逆向執行安裝操作。(這裏存在的問題是,這個 uninstall.exe 真的能把軟件卸載幹凈麽?於是就產生了各種問題。)
相對的,Linux 的包管理工具,(常見的有apt-get/dpkg yum/rpm)也需要 root權限,安裝時會將軟件的依賴、安裝位置等信息寫入某個地方,在卸載時會執行安裝的逆向操作,不過一般只卸載軟件本身,而不會卸載依賴。使用 apt-get 的話,需要用 autoremove 選項,這樣卸載時,也會自動卸載依賴。(從軟件倉庫在線安裝和下載 deb rpm 離線安裝都屬此類)
而免安裝軟件呢,Windows 和 Linux 都差不多。只需要將軟件解壓(下載好的軟件應該是 tar.gz 或 zip 格式,需要解壓),就能直接用了。Linux 的啟動方式應該是 bin 目錄下的啟動腳本之類,而 Windows 上,一般就是安裝目錄下與軟件同名的 exe 程序。
免安裝軟件需要用戶自己記住安裝位置,要刪除的時候,直接刪除掉解壓出來的文件夾就行了。(如果使用程序時,它沒執行過其他操作的話。)
Windows 的用戶群大,安裝版軟件最流行,這種方式能方便用戶管理自己安裝的軟件。而且 Windows 軟件體系的兼容性做得特別好,十年前在 Xp 上編譯的軟件,很可能仍然能在最新的 Win10 流暢運行。(這也是形勢所迫吧,在 Windows 上,讓普通用戶去從源碼編譯幾乎是不可能的,因此開發者別無選擇,只能發布 exe 格式。)
而 Linux 是開源操作系統,因此默認不能包含任何非開源的軟件。如果需要這類非開源的軟件,用戶只能自行安裝。Linux 系的軟件有如下特色:
- Linux 系的開源軟件,如果是用戶群少的或者更新很快的,可能只會發布源碼tarball,需要自行編譯安裝,不會發布各平臺的編譯版。即使有編譯版,也可能只會提供 deb rpm 這樣用戶群大的,還可能不會及時更新。(Linux 社區崇尚開源,這和 WIndows 截然不同。不過這也使 Linux 的軟件安裝過程受人詬病)
- 用戶群大的商業軟件,如 Jetbrains 系,只發布通用的二進制 tar.gz 包,也就是免安裝版,而 Oracle JDK 則只發布 tar.gz 和 rpm.(大概考慮到很多 CentOS 服務器有用 JDK 吧)
- 用戶群大的開源軟件,一般會提供 tar.gz 的源碼和 binary.tar.gz.
總結一下就是,Linux 方面,通用的免安裝包好像很流行,而安裝包只能用於特定發行版,不太討喜。
使用 Linux 的大部分都是程序員,因此源碼版也很受歡迎。從源碼安裝有更大的自由度,編譯出的程序也可以特定於自己的電腦,省去很多兼容性的東西。簡單的說就是更快更爽。
那下面就分這三種情況,分別討論軟件的安裝、卸載。
2. 免安裝二進制tarball
這種包一般是 tar.gz 或 tar.xz 格式,解壓後,cd 到 bin 目錄,裏面會有一個與軟件同名的腳本或可執行文件,直接運行它就啟動軟件了。而且這種包貌似是能在各發型版上通用的(eg. pycharm nodejs jdk etc.)
一般我們在 Linux 上安裝了軟件後,都希望能夠在 shell 裏直接啟動它。要做到這個,需要先了解 Linux 的 shell 環境變量配置文件
- 全局環境
- /etc/profile 系統的 shell 環境配置文件(僅每個用戶登錄時加載一次,不建議修改)
- /etc/bash.bashrc 系統的 bash shell 環境配置文件(每次開啟一個新 bash,都會加載。如果需要對所有用戶都生效的 bash 環境,就修改這個)
- 用戶環境
- ~/.profile [也可能是 ~/.bash_profile] 用戶個人的 shell 環境配置文件,相當於 /etc/profile 的個人 patch。一般來說它設定一些用戶個人的環境變量,然後執行 ~/.bashrc。
- ~/.bashrc 用戶個人的 bash shell 配置文件(同樣每次開新 bash 都會加載)
- source :在當前 shell 中執行指定的 shell 腳本。常用於環境設定檔。(這樣做,運行後的變量會存在於當前shell,也就完成了所謂的環境設定。而如果是普通的直接運行的話,會啟用新shell來運行該腳本,運行結束環境就銷毀了。)
由上述配置文件引申,用戶安裝二進制 tarball 時,通常有兩種做法:
一種就是將該軟體的 bin 目錄添加進PATH中(這會使該 bin 目錄中的所有可執行文件都被加入到 PATH,如果你不想這樣,請考慮第二種方法),也就是將相關命令寫入 shell 配置文件中。至於應該添加到哪裏,看了上面的說明,你應該已經懂了。
舉例來說,安裝一個軟件時,如果該軟件大家都要用,就應該寫入系統配置裏,然後如果你基本只用 bash,寫 bashrc 裏更方便(修改可立即生效),否則選profile。
而若只有你個人需要該軟件,肯定要放用戶配置裏,再考慮你是不是用其他 shell。一般來說放 bashrc 裏總沒問題,而放 profile 裏,有時會需要手動source /etc/profile
一下才能用。第二種呢,就是向PATH默認就會包含的那些目錄中(例如 /usr/local/bin),添加啟動腳本。(使用 python 或 shell 編寫)Jetbrains 家的軟件在檢測到該軟件的 bin 目錄未添加進 PATH 時,就會提示你這麽幹。(idea 會向 /usr/local/bin 添加名為 idea 的 python 啟動腳本)
而如果是 JDK 這種需要在配置環境變量的軟件,這之後你還需要手動配置 JAVA_HOME、CLASSPATH等。
3.使用安裝包安裝
這種方式就和 Windows 的安裝包類似,但是該安裝包只能用於特定的發行版,因為不同的發行版使用不同的包機制。最常見的是dpkg 和 rpm,它們也存在對應的在線安裝機制,就是apt-get 和 yum.
待續
4. 從源碼編譯安裝
從源碼編譯安裝好處已經說了,自由度更高,兼容問題更少,性能更高等。缺點就是編譯比較麻煩,而且安裝好的軟件也不好管理。
gcc 編譯套件(編譯 + 鏈接)
說到編譯,一般都是 c/c++ 源碼,那在詳細說明之前,這裏有些目錄需要先介紹。
- /lib、/lib64:共享鏈接庫,包括靜態鏈接庫 *.a,和動態鏈接庫 *.so. 使用 gcc 編譯時,默認會從這裏查詢需要的鏈接庫。不在此列的鏈接庫需要用
-l單個鏈接庫
或-L/鏈接庫所在文件夾
來指定。 - /usr/include:系統頭文件的保存處,使用 gcc 編譯時,默認會從這裏查詢需要的系統頭文件。不在此列的頭文件目錄需要使用
-I/頭文件所在文件夾
來指定(是大寫的 i)
make 軟件構建工具
在軟件變得龐大時,如果還手動地一次次調用 gcc,就變得不太現實了。這個時候為了讓計算機自動化地處理這種項目的編譯構建過程,make 誕生了,它依賴 Makefile。(如果項目變得更龐大,即使是手寫Makefile也變得很困難,這時出現了cmake。cmake是用來自動生成Makefile的,它依賴於 CMakeList.txt)
不過流行的開源軟件,makefile.txt 的生成規則早就已經寫在 configure 裏了,你需要做的只是
./configure
make
sudo make install
如果使用的是cmake,那就用cmake .
替換掉./configure
就行。(有時為了隔離編譯相關文件和源碼,會先創建一個build文件夾,再在該文件夾內運行cmake ..
)
話雖如此,還是需要先安裝好編譯需要的依賴,才能正常編譯,否則在./configure
這一步就會報錯。要從源碼安裝一個軟件,最痛苦的不是在make,而是在處理依賴。要是這依賴的安裝也能自動化就好了。。。
源碼安裝軟件的刪除
從源碼安裝的軟件雖有諸多好處,但是軟件的管理就有點麻煩。首先很多的軟件作者都不會提供相應的make uninstall
命令,因此這麽卸載軟件並不通用。
在使用 make install
安裝好軟件後,一定要記得備份安裝生成的install_manifast.txt
,再刪除掉源碼。(這個文件一般會有寫保護)
這之後,如果需要卸載,直接xargs rm < install_manifest.txt
就行了
可以創建一個備份目錄,專門備份和系統有關的的資料,/etc 和 上述的 install_manifest.txt(建議改名為「軟件名_install_manifest.txt」)都可以算作此類。
參考
- 第二十一章、軟體安裝:原始碼與 Tarball
- 怎麽卸載用 make install 編譯安裝的軟件?
Linux 的軟件管理 - 安裝、卸載、升級 和 依賴管理