簡介

Pacman 是 Archlinux 所使用的套件管理系統。支援相依性(dependency)、套件組(package groups)、安裝與反安裝、與遠端伺服器自動同步更新套件。

Pacman 的套件包其實是一個 tar 的 gzip 壓縮檔,常以 .tar.gz 作為檔名結尾。

從 3.0.0 版開始,pacman 架構於 libalpm (Arch Linux Package Management library) 之上,成為 libalpm 的前端程式(frontend),換句話說,若有人想的話,可以利用 libalpm 自己寫一個套件管理程式。

本篇筆記是在 Pacman 3.5.2 時整理的。

設定套件庫

Pacman 使用 libalpm,會在每次執行時都去讀取 /etc/pacman.conf,設定檔內包括 pacman 全域行為的選項與使用 --sync 時的套件庫設定。

Options
  • RootDir = path/to/root

    指定 pacman 安裝套件時使用的 default root 資料夾。如果想把套件安裝到來自其他系統、暫時掛載的 partition,或準備 chroot 環境,就會用到這個設定。注意:如果在設定檔與命令列均無指定 databse path 或 logfile,預設會參考這裡指定的 root 位置。

  • DBPath = /path/to/db/dir

    指定 database 資料夾的預設位置。通常預設是 {localstatedir}/lib/pacman/ 。注意:如果指定了,必需是絕對路徑,前頭不會自動加上根目錄。

  • CacheDir = /path/to/cache/dir

    指定 cache 資料夾的預設位置。通常預設是 {localstatedir}/cache/pacman/pkg/ 。可指定多個 cache 資料夾,pacman 會依序嘗試。如果 cache 資料夾內沒有找到檔案,就會把檔案下載到第一個具有寫入權限的資料夾。注意:必需用絕對路徑,前頭不會自動加上根目錄。

  • Logfile = /path/to/file 指定 pacman log file 的預設位置。通常預設是 {localstatedir}/log/pacman.log 。注意:必需用絕對路徑,前頭不會自動加上根目錄。

    從 manpage 的說明看來,如果有指定 Logfile、CacheDir、DBPath,路徑的根目錄是相對於原來的 root,而不是 RootDir 指定的根目錄,如果沒有指定 Logfile、CacheDir、DBPath,就會使用相對於 RootDir 裡的相對預設位置。

  • HoldPkg = package …

    如果使用者嚐試移除這裡指定的套件,pacman 在進行移除前會事先要求確認。

  • IgnorePkg = package …

    執行 --sysupgrade/-u 時,忽略這邊指定的套件。可指定多個套件,用空白隔開。

  • SyncFirst = package …

    告訴 pacman 在進行任何 sync 操作前先檢查這邊指定的 packages 是否有新版,然後請使用者決定是否先暫時取消目前動作、更新這裡指定的套件,或繼續目前動作。注意:使用 SyncFirst 時,不會接受任何命令列的選項(e.g. --force),如果這麼作會有問題,請不要用 SyncFirst,改用手動 sync。

  • IgnoreGroup = group …

    執行 --sysupgrade/-u 時,忽略這邊指定的套件組內的所有套件。可指定多個套件組,用空白隔開。

  • Include = path

    讀入其他設定檔。這可以包括套件庫(repositories)或選項(option)的設定。在指定的路徑中使用萬用字元會被依 glob(7) 的規則代換。

  • Architecture = auto | i686 | x86_64 | …

    如果指定了 Architecture,pacman 將會只允許安裝這裡所指定的平台的套件,如設為 auto,會使用 "uname -m" 的值。如果不指定,就不會檢查平台。注意:某些套件的 architecture 如果設為 any,就可以在所有平台上安裝,這些套件通常是不依賴特定平台就可以正常作用的。

  • XferCommand = /path/to/command %u

    如果有設定,就會用這邊的外部程式來下載所有遠端的檔案。所有的 %u 會被取代成下載URL,%o 會被代換成存在本機的檔名,並會在後面加上 .part 以便像 wget 之類的程式可以續傳。

  • NoUpgrade = file …

    這邊列出的檔案,不管是安裝或升級套件,都不會去動它,新的檔案會在安裝時在檔名後面加上 .pacnew。這裡的檔案路徑是相對於套件包,所以前面不要加上根目錄,要用相對路徑。

  • NoExtract = file …

    這邊列出的檔案,永遠不會被解出來放到檔案系統,這在你不想安裝套件中某些檔案時可能用得到。例如:如果你的 httpd root 使用 index.php,你可能不想安裝 apache 套件中的 index.html,只要在這邊指定,就可以不要安裝這個檔案,注意,路徑要用相對路徑,前面不要加根目錄,用套件包內的檔案路徑。

  • CleanMethod = KeepInstalled &| KeepCurrent

    預設是 KeepInstalled,使用 -Sc 時會清除 cache 中沒有安裝(不在 local database 中)的套件。如果設為 KeepCurrent,-Sc 會清除過期(不存在於任何 sync database 中)的套件,這在多台電腦共用套件 cache 時很有用,因為 local databases 通常不同,但 sync databases 都相同。如果兩個值都指定,只會清除 cache 內本機未安裝且不存在於任何 sync database 的套件。

  • UseSyslog

    透過 syslog() 來記錄動作訊息,這會在 {localstatedir}/log/messages 或相當於此檔的其他地方加入動作記錄。

  • ShowSize

    在 --sync 與 --query 時顯示個別套件的大小

  • UseDelta

    如果可能,下載 delta files 而不是完整套件,需要 xdelta3。

  • TotalDownload

    下載時,顯示整份下載清單已下載的大小、下載速率、ETA、與完成率,而不是個別目標。進度條仍然完全以目前下載的檔案為準。

  • CheckSpace

    在安裝套件前大約檢查一下磁碟可用空間

套件庫 (repository) 設定

每個套件庫都有一個 section name,並至少要有一個位址,在那邊應該要可以找到套件包。Section name 用方括弧[]包著,如 [core]、[extra]、[community]、[multilib],位址則用 Server = URL 來定義,如果想用本機的資料夾作為來源,開頭改成 "file://"。

DB locations 常用 Include 的方式,對於每一個設定檔中定義的 repository,可以有一個 Include 定義,值應該是可供套件庫使用的 servers,如:

           [core]
           # use this repository first
           Server = ftp://ftp.archlinux.org/core/os/arch
           # next use servers as defined in the mirrorlist below
           Include = {sysconfdir}/pacman.d/mirrorlist

在處理設定檔時,pacman 會把 $repo 變數定義為目前的 section name(如:core, extra, community),這常在 Include 指定的檔案中使用,如此一來,所有套件庫都可使用同一個 mirrorlist。Pacman 也定義了 $arch 變數,代表平台(Architecture),所以相同的 mirrorfile 甚至可以用於不同的平台,如:

Server = ftp://ftp.archlinux.org/$repo/os/$arch

設定檔中套件庫的順序是很重要的,會依順序處理。當不同套件庫有同名的套件時,先列出的套件庫會優先。

自訂的套件庫

如果有多個自訂的套件,可以自行定義一個本機的套件庫,如此就不用事後再手動安裝。要做的事是—在想作為套件庫的資料夾內產生一個壓縮的套件資料庫檔,以便進行 pacman -Sy (--refresh) 時可以找到相關資料。

repo-add /home/pkgs/custom.db.tar.gz /home/pkgs/*.pkg.tar.gz

這個命令會產生一個壓縮的資料庫 /home/pkgs/custom.db.tar.gz。後面的 *.pkg.tar.gz 則是要加入套件庫的套件包檔名。注意:資料庫的格式一定要和設定檔一樣。

repo-add 與 repo=remove 是兩支幫忙管理本機套件資料庫的 scripts。repo-add 會讀取套件檔並更新套件資料庫,repo-remove 會移除指定的套件並更新套件資料庫。可指定多個套件,中間用空白隔開。

Pacman 的幾個主要「操作」(operation)

Pacman 有幾種主要的「操作」,每種操作可搭配細部的選項(option)來完成各種任務

  • -D, --database

    修改套件資料庫。這個操作主要是讓你可以修改 pacman 資料庫中已安裝套件的某些屬性。以目前而言,只能用 --asdeps 與 --asexplicit 這兩個選項來改變套件安裝的理由。

    已安裝的軟體,pacman 會將資訊加到 /var/lib/pacman/local 中,以下將用 local database 來稱呼。

  • -Q, --query

    查詢套件資料庫。這個操作讓你可以檢視已安裝的套件與它們的檔案,以及套件的相依性、衝突、安裝日期、編譯日期、大小……等。可以查詢本機(local)的套件資料庫,也可以查詢個別的 .tar.gz 套件包。如果沒有指定,會顯示所有已安裝的套件。透過細部的選項(option),可以更進一步指定要查詢的條件與對像。

  • -R, --remove

    從系統移除套件。也可以指定移除整個套件組(group)。移除後,會刪掉套件在系統中的檔案並更新套件資料庫。除非指定 --nosave,大部分設定檔會在檔名結尾加上 .pacsave 備份起來。

  • -S. --sync

    將套件同步化,其實就是直接由 ftp servers 下載、安裝套件,並自動安裝該套件相依的套件。如果不同套件庫(repo)有相同的套件名稱,可以指定要安裝那一個,如 pacman -S testing/qt。也可指定版本,如 pacman -S "bash>=3.2"。(要加 quote,否則會被 shell 當成 redirection to file)

    除了套件,也可以直接同步套件組(group)。例如:如果有個 package group 叫 gnome,pacman -S gnome 就會安裝 gnome group 內的所有套件與其相依的套件。

    遇到 server 沒有提供的套件時,pacman 會自動建議其他功能類似的套件。例如:pacman -S foo 首先會尋找 foo 這個套件,如果沒有,就會建議是否安裝其他功能類似 foo 的套件。

    pacman -Su 可以升級所有過時的套件。

    Alphanumeric:
    1.0a < 1.0alpha < 1.0b < 1.0beta < 1.0p < 1.0pre < 1.0rc < 1.0
    
    Numeric:
    1 < 1.0 < 1.1 < 1.1.1 < 1.2 < 2.0 < 3.0.0
  • -T, --deptest

    測試相依性。這在寫 scripts 時很有用,例如用 makepkg 來測試已安裝的套件。這個操作會檢查每一個指定套件的相依性,並傳回目前尚未滿足的東西。這個操作沒有其他細部選項。使用方式如:pacman -T qt "bash>=3.2"。

  • -U, --upgrade

    更新或加入套件到系統,並由同步的套件庫安裝所有相依套件,可指定 URL 或 file path。這是一個「先移除再新增」的過程,可藉細部的選項與設定檔來調整某些行為。

  • -V, --version

    顯示版本資訊

  • -h, --help

    顯示某動作(operation)的語法。如果沒有指定動作,就顯示一般的語法

Options

  • --arch <arch>

    指定平台(architecture)

  • --cachedir <'dir'>

  • --config <'file'>

    指定設定檔的位置

  • --logfile <'file'>

    指定使用的 log 檔。必需使用絕對路徑,不會考量安裝的 root 位置。(注意 -r 的說明)

  • -b, --dbpath <'path'>

    指定 database 路徑(通常是 /var/lib/pacman)。通常不需要用到。 注意:如有指定,路徑必需是絕對路徑,前頭不會自動加上根目錄(/)

  • -r, --root <'path'>

    指定安裝時檔案系統的 root (預設是 /)。不要為了純粹改變安裝路徑而使用這個選項(例如:不想將檔案裝到 /usr、要將檔案裝到 /usr/local),這個選項是當你想將套件安裝到某個暫時掛載的磁碟分區(來自另一個系統)時使用的。(注意:如果沒有在 pacman.conf 或命令列指定 database 路徑與 logfile 路徑,預設的位置會到這邊所指定的 root 內。)

  • --noconfirm

    跳過任何詢問 "Are you sure?" 的詢息。通常不需要使用,除非你想在 script 中執行 pacman。

  • --debug

    顯示 debug 訊息,回報問題時,建議使用這個選項。

  • -v, --verbose

    輸出時顯示 Root、Conf file、DB Path、Cache Dirs 等路徑。

Transaction Options (適用於 -S, -R, 與 -U)

  • -d, --nodeps

    跳過版本相依性的檢查(仍會檢查套件包名稱)。正常來講,pacman 會檢查套件包的相依性欄位,以確定有滿足所有的相依性,且系統內沒有衝突的套件。如用 -dd,就會跳過所有相依性的檢查。

  • -k, --dbonly

    只在 database 新增/移除記錄,讓所有檔案留在原位

  • --noprogressbar

    下載檔案時不要顯示進度條(progress bar)。這對某些執行 pacman 並截取其輸出結果的 script 可能有些用處。

  • --noscriptlet

    如果有 install scriptlet 存在 ,不要執行它。除非你知道自己在做什麼,否則不要使用。

  • -p, --print

    只列出目標套件的名稱,不執行實際操作(sync, remove, upgrade)。可用 --print-format 來指定目標套件顯示的格式。預設的格式字串是 "%l",在 與 -S 配合時顯示 URL、與 -U 配合時顯示檔名、與 -R 配合時顯示 pkgname-pkgver。

  • --print-format <format>

    以類似 printf 的格式來顯示 -print 的輸出結果。 %n 代表 pkgname,%v 代表 pkgver,%l 代表 location,%r 代表 repo,%s 代表大小。

Upgrade Options (適用於 -S 與 -U)

  • -f, --force

    跳過檔案衝突的檢查並覆蓋所有衝突的檔案。如果要安裝的套件內有某些檔案在系統內已存在,指定這個選項後,系統內的檔案會被新安裝套件的檔案蓋掉。所以此選項要小心使用,不需要用最好。

  • --asdeps

    「不明確地」(non-explicitly)安裝套件。換句話說,就是騙系統說,安裝此套件是為了相依性(dependency)。這對 makepkg 與其他從原始碼編譯的工具而言相當有用

  • --asexplicit

    「明確地」(explicitly)安裝套件。換句話說,就是騙系統–此套件是我們明確指定要安裝的。使用這個選項後,自動安裝的相依套件,會被標示成「是我們指定要安裝的」,亦即,當使用 --remove --recursive (-Rs) 時,不會自動移除這些套件。

  • --ignore <package>

    告訴 pacman 忽略這邊所指定的套件的升級,即使這些套件有新版。可用逗號隔開多個套件。

  • --ignoregroup <group>

    告訴 pacman 忽略這邊所指定的套件群組的升級,即使這些套件群組有新版。可用逗號隔開多個套件群組。

Pacman 操作示例

求救

  • 查詢 pacman 的主要操作

    man pacman
    pacman -h
  • 查詢 pacman 主要操作的選項

    pacman -Dh
    pacman -Qh
    pacman -Rh
    pacman -Sh
    pacman -Th
    pacman -Uh

瞭解套件庫的狀況

  • 從遠端的套件庫更新套件資訊(相當於 aptitude update,會依據 /etc/pacman.conf 中的設定,更新 /var/lib/pacman/sync/ 中的資料庫)

    pacman -Sy
  • 搜尋套件資料庫(sync database)中名稱或描述中包含關鍵字 REGEX 的套件

    pacman -Ss REGEX

    注意:這裡的 REGEX 是指正規表達式(regular expression)。如指定多個條件(用空白隔開),只會列出滿足所有條件的套件。

  • 列出 sync database 中套件 XXX 的資訊(如果沒有指定套件,會列出所有套件的資訊)

    pacman -Si XXX
  • 列出 sync database 中套件 XXX 的資訊,並列出所有 repositories 中相依於此套件的套件

    pacman -Sii XXX

瞭解本機的狀況

  • 列出已安裝套件的清單(預設由 /var/lib/pacman/local 查詢,可用 -b /path/to/database 自定資料庫位置)

    pacman -Q
  • 查詢已安裝套件中符合 REGEX(正規表達示) 字串的套件

    pacman -Qs REGEX
  • 查詢已安裝套件 XXX 的資訊(可查 required by、depends on、與 install resaon、size 等重要套件資訊)

    pacman -Qi XXX
  • 查詢套件包的資訊

    pacman -Qpi /path/to/XXX.pkg.tar.xz
  • 查詢已安裝套件 XXX 所打包的檔案

    pacman -Ql XXX
  • 查詢套件包內的檔案

    pacman -Qpl /path/to/XXX.pkg.tar.xz
  • 查詢系統中某個檔案是那一個套件所提供的

    pacman -Qo /path/to/file
  • 查詢套件 XXX 的更新記錄

    pacman -Qc XXX
  • 查詢套件包 XXX 的更新記錄

    pacman -Qpc XXX.pkg.tar.xz
  • 查詢自己明確地(explicitly)安裝的套件清單(-e),且不要列出版本號(使用 -q 的好處是,弄成套件清單,方便再次利用)

    pacman -Qeq
  • 查詢因相依自動安裝的套件

    pacman -Qd
  • 查詢系統之前因相依自動安裝(-d)、但現在已沒有其他套件需要(-t)的套件

    pacman -Qdt
  • 查詢已安裝、但沒有在 sync db 內的套件(例如:自己編譯的套件)(-m),並且不要列出版本號(-q)

    pacman -Qmq
  • 檢查系統中特定套件 XXX 的所擁用檔案的完整性(如不指定套件,會檢查整個系統)

    pacman -Qk XXX
  • 查詢系統中可升級的套件

    pacman -Qu

管理系統的套件

  • 安裝套件 XXX 與 OOO (由套件庫下載)

    pacman -S XXX OOO
  • 安裝某套件庫內的套件 XXX (有時不同的套件庫可能有同名但不同版本的套件)

    pacman -S extra/XXX
    pacman -S testing/XXX
  • 安裝由網路下載或自行編譯的套件包 XXX

    pacman -U /path/to/XXX.pkg.tar.xz
  • 全系統升級

    pacman -Su
  • 全系統升級(--ignore 後指定的套件除外)

    pacman -Su --ignore kernel26,kernel26-headers,linux-firmware
  • 僅下載套件 XXX,不安裝

    pacman -Sw XXX
  • 移除套件 XXX (僅移除指定的套件,不包含相依的套件)

    pacman -R XXX
  • 移除套件 XXX (移除 XXX,並自動移除 XXX 依賴的套件)

    注意:pacman 自動移除的相依套件,需滿足兩個條件,第一,沒有其他套件需要它;第二,不是使用者「明確地」(explicitly)安裝它的

    pacman -Rs XXX
  • 移除套件 XXX (移除 XXX,並自動移除依賴 XXX 的套件,請小心使用,這個選項可能移除仍然必要的套件)

    pacman -Rc XXX
  • 移除套件 XXX,並且不理會需要備份的檔案(通常在移除套件、更新套件時,套件包可能會指定某些檔案需要備份,這些檔案會在檔名後加上 .pacsave,如果使用 -n/--nosave,就不會產生 *.pacsave)

    pacman -Rn XXX

維護系統資料庫

  • 清除 cache 中不再用來安裝的套件(packages)以及不再使用的同步資料庫(sync database)

    pacman -Sc
  • 清除 cache 中的所有套件與同步資料庫

    pacman -Scc

群組管理

  • 列出所有可安裝的 groups

    pacman -Sg
  • 列出所有可安裝的 groups 與其所包含的套件

    pacman -Sgg
  • 已定義的 group XXX 內包含的套件

    pacman -Sg XXX
  • 目前已安裝套件中有被列入 groups 的套件名稱以及所屬的 group

    pacman -Qg
  • 安裝 group XXX

    pacman -S XXX
  • 移除 group XXX

    pacman -R XXX

Pacman 處理備份檔的方式

Pacman 使用與 rpm 相同的邏輯來處理需要備份的檔案。升級套件時,每個被指定需要備份的檔案都使用三個 MD5 hashes,一個是原始安裝的檔案(original)、一個是將要安裝的檔案(new)、一個是目前檔案系統中實際存在的檔案(current)。比較過這三個 hashes 後,按情況來處理。

  • original=X, current=X, new=X

    三個檔案相同,所以覆蓋不會造成問題,直接安裝 new file。

  • original=X, current=X, new=Y

    目前檔案與原始檔案相同,但新版套件內的檔案不同。因為使用者沒有修改過檔案,而 new 中可能有新版的改善或修正,故安裝 new file。

  • original=X, current=Y, new=X

    舊版與新版的套件包含相同的檔案,但檔案系統中的檔案已經被修改過了。此時會保留 current file。

  • original=X, current=Y, new=Y

    新版的檔案與目前檔案系統中的相同。安裝 new file。

  • original=X, current=Y, new=Z

    三個檔案都不同,所以會安裝新版檔案 new file,但在檔名結尾加上 .pacnew,這是為了警告使用者,使用者必需自行手動更新。

名詞對照

  • repo/repository: 套件庫

  • operation: 操作

  • option: 選項

  • dependency: 相依性

  • explicitly: 明確地

  • non-explicitly: 不明確地