為什麼說Arch Linux的pacman包管理系統更先進?相比與apt或rpm等好在哪裡呢?


我在別的系統上的經驗並不多,沒有 rpm/deb 打包的經驗,只說說 Arch Linux 上的感受。

從包管理的能力上說, pacman 並不比 apt 系和 rpm 系的包管理器好,可能比 apt/rpm 還弱一點。ArchWiki 上有個 Pacman/Rosetta 對比 pacman 的命令和別的系統的命令,可以看到很多事情別的系統有命令支持而 pacman 沒有對應的命令選項。具體的特性來說 pacman 4.x 才有了簽名驗證,最近 5.0 才剛剛有了 hook 支持和搜索源里的文件,而這些都是別的包管理器上早就有的功能了。

從技術架構上來說, pacman 比 apt/rpm 新很多,從而能做到一個 C 寫的程序(以及現在分出了一個 C 的庫 libalpm)涵蓋絕大多數核心功能。這至少有兩點好處:

  1. 統一的命令格式。所有命令都是 pacman 加一個主要動作(D/S/Q/R/U/F/T)加一些額外選項(s/w/u之類的)加目標,清晰簡潔。不像 apt/rpm 系都有很多不同的前端支持不同的命令格式,誰能幫我理清楚 dpkg/apt-get/apt-cache/apt 之間的關係?
  2. 更少的依賴使其更加獨立。不像 apt/rpm 系的包管理工具經常依賴大量的庫,甚至要依賴 perl/python 環境才能用, pacman 非常獨立,甚至有個 pacman-static 在 AUR 里根本不依賴任何庫包括 libc 。這一點對包管理器來說至關重要,因爲面對一個病入膏肓的系統,你通常需要依賴包管理器本身能正常工作從而修復好系統,如果包管理器有太多依賴關係,那麼它壞掉的概率就大大增加了。

除了功能統一在一個程序之外, pacman 還有一點好處,其輸入輸出格式和數據庫記錄格式非常規整,不僅人可以用,而且很容易被別的程序解析,很容易用 unix 管道組合起來完成複雜的工作。

舉個例子, apt-get/dnf 都有個命令 autoremove 作用是刪除不再需要的依賴包, pacman 做這個事情是用一個管道:

pacman -Qtdq | pacman -Rs -

稍微解釋一下, -Q 是搜尋本地已經安裝的包, t 是篩出不被別的包依賴的包,d 是篩出當初安裝的時候作爲依賴裝進來的包, td 兩個結合就是篩出孤兒包,然後 q 選項讓輸出格式只有包名。管道傳給後面 -R 是刪除包,s 是遞歸刪除這些包的依賴,後面還有一個短橫是說這個 pacman 的目標不寫在命令行選項而從標準輸入(這裡是管道)里讀取。

乍看起來似乎很複雜,但是習慣了之後這套就顯得很方便而且靈活。比如你想在刪除前看一遍包列表?管道中插入個 vipe 命令就可以了。

以上大概就是 pacman 僅有的優勢了。從良心來講優勢並不很明顯,談不上所謂的先進,甚至可能比別的包管理器更粗糙一點。

真正可以說先進的地方,大概不是 pacman 本身,而是 pacman 背後的 Arch Linux 所崇尚的簡潔主義哲學。推崇簡潔使得 pacman 在設計的時候就不需要考慮很多別的系統會遇到的複雜問題。

舉個例子談一下 pacman/Arch Linux 對依賴關係的處理。乍看起來 Arch Linux 和別的系統在依賴關係上就是粗放打包和精細打包的區別而已,實質上更重要的是, Arch Linux 的滾動更新模型不支持「部分更新(partial update)」。部分更新簡單地說就是系統中只選擇性地更新一部分包而不更新所有包。

考慮 A 和 B 各自依賴 C ,現在你想更新 B ,新的 B 需要新的 C 庫,於是要同時更新 C ,這個更新會不會破壞 A 呢?很有可能。所以要支持部分更新的話,就要考慮每個包之間的版本依賴。所以你去看 debian/fedora/opensuse 里的依賴關係,都是一長串包版本的區間範圍,他們必須寫清楚 A 1.2.3 依賴 C &>=1.0.0 並且 C&<=1.9.8 這種關係。而在 Arch Linux 這邊,由於不支持部分更新,所以大多數情況下寫個 A 依賴 C 就足夠了。同樣由於要考慮部分更新,debian/fedora/opensuse 那邊每次更新一個包,實際上都是在全系統範圍內解決一個非常龐大的布爾不等式滿足問題(Boolean satisfiability problem),理論上這是一個複雜的 NPC 問題,所以他們都引入了複雜的 SAT solver (比如GitHub - openSUSE/libsolv: Library for solving packages and reading repositories) 去算出一個或者多個可行的解,然後每次升級都可能升一部分包的版本,降另一部分包的版本,安裝一些包,再刪除另一些包,最終滿足全局的依賴關係,或者在不可能滿足的情況下給出多個最小的破壞依賴關係的方案。有沒有聽起來很複雜?

反觀 Arch 這邊,由於大多數依賴關係都是 「A 依賴 C」這種簡單明瞭的關係,大多數情況下把所有包裝到最新就能解決了,如果不能滿足,那麼 pacman 就簡單地罷工報錯,讓用戶自己想辦法手動去解決。

pacman 生長在 Arch Linux 這種崇尚簡潔不多管閒事的氛圍中,秉承做一件事並且把它做好的優良 Unix 傳統,使得它小巧輕便,快速簡潔。很多 debian/fedora/opensuse 用戶可能會感覺到升級一下系統是個大工程,敲一下 update/upgrade 命令就會有數百行輸出從屏幕上滾過,要從幾十個不同的地方下載各種數據庫和包,耗時良久,還不一定能正常結束,經常問一堆聽不懂的問題不知道怎麼回答。 Arch Linux 這邊經常有用戶 pacman -Syu (最基礎的升級命令)上癮,隔十分鐘就滾一下(就像有些畫師 Ctrl+S 上癮),下載更新也都非常迅速快捷。pacman 的速度優勢主要就來源於它用 C 實現以及不多管閒事的態度上,這或許也就是它先進的地方吧。


好處是可以在 Windows 上 MSYS2 用 pacman ...

OSX 也可以 ...


pacman並不更先進。如果把yaourt也算進來,實際上是更落後,因為後者沒有能力同時更新多個包,遇到某個包和依賴必須一起更新就只能手動操作。例如AUR里的包A 1.0依賴B,而A 1.1依賴C,C與B衝突,yaourt無法完成更新。


就說一個關於配置文件的管理吧。

當pacman卸載一個軟體包時,如果軟體包裏包含配置文件,並且這個配置文件在安裝過後被人爲修改過(md5校驗和發生變化),則把該文件重命名爲.pacsave的後綴,用以備份。

當pacman升級一個軟體包時,如果配置文件有更新,而且當前版本的配置文件被人爲修改過,那麼新版配置文件不會覆蓋當前版本,而是會創建一個.pacnew後綴的配置文件,並且在升級過程中提示您手動檢查配置文件,手動合併。pacman提供了一個叫pacdiff的工具,會調用vimdiff輔助你進行合併。

對於包升級過程中的每個備份文件,pacman 會交叉校驗三個版本的文件內容生成的 md5 值:一個為軟體包最初創建的版本,一個為文件系統中當前的版本,還有一個為新軟體包中的版本。

引用wiki中的說明:

3路MD5值校驗結果為下述輸出之一:

original = X, current = X, new = X

三個版本的文件具有相同的內容,因此覆蓋不會產生問題。pacman 將用新版本覆蓋當前版本而不通知用戶。(儘管文件內容相同,覆蓋操作會更新文件系統中和文件創建,修改和訪問時間有關的信息,也確保了任何文件許可權的修改被實施。)

original = X, current = X, new = Y

當前版本文件的內容和原始版本的相同,但與新版本不同。既然用戶沒有修改過當前版本文件,且新版本可能包含改進和 bug 修正,pacman 用新版本覆蓋當前版本,而不通知用戶。這是 pacman 有能力執行的唯一一個新改動的自動合併。

original = X, current = Y, new = X

原始軟體包和新軟體包都包含版本完全相同的文件,但當前文件系統中的版本是被修改過的。此時 pacman 保留當前版本,忽略新版本,且不通知用戶。

original = X, current = Y, new = Y

新版本和當前版本相同。此時 pacman 將用新版本覆蓋當前版本且不通知用戶。(儘管文件內容相同,覆蓋操作會更新文件系統中和文件創建,修改和訪問時間有關的信息,也確保了任何文件許可權的修改被實施。)

original = X, current = Y, new = Z

三個版本的文件都不相同,所以保留當前版本,以擴展名 .pacnew 創建新版本,且警告用戶創建了新版本。希望用戶手動將需要的更改由新版本合併至當前版本。


就像別的答案說的,不是pacman先進,是Arch先進,或者Arch的理念先進。


先不先進不清楚,但是說 pacman 乾淨利索應該沒多少人反對吧。


arch linux 日常吹。。。


pacman並不先進。同樣archlinux也並不先進。只是特色比較鮮明。


感覺pacman很簡陋的感覺,這就是咱第一次pacman的感覺,可是用久了會覺得跟apt對比沒有劣勢呀,反而還感覺輸出的內容更加簡潔了。現在一直在想能不能把樹莓派的apt-get也換成pacman。。。


先進不先進意義不大,好用和用慣了才是決定性因素。

說先進的大多都是自己給自己加自豪感。

譬如說我覺得zypper也是很先進,YaST更能方便的管理,你讓一個用慣了zypper和YaST的人去用Arch Linux那指定是不願意。

如果你讓一個用了很久deb系更新的人去用pacman那他也肯定是無所適從,習慣性的就敲下了apt-get,就像我經常在Windows上敲ls一樣。


推薦閱讀:

用作生產環境伺服器,FreeBSD和CentOS相比有哪些優劣勢?
工業中為什麼很少採用 Linux 伺服器?
如何理解內核搶佔和用戶進程搶佔,他們的區別是什麼?
linux 下進程間的同步機制有哪些?

TAG:Linux | ArchLinux | 包管理器 |