pacman - Arch Linux 中文维基

跳至內容

# pacman

出自 Arch Linux 中文维基

翻譯狀態：

- 本文（或部分內容）譯自 pacman，最近一次同步於 2024-05-22，若英文版本有所更改，則您可以幫助同步與翻譯更改的內容。
- 您可以在 ArchWiki 的對應頁面找到本文翻譯的原始修訂歷史。
- 本文可能與英文原文存在出入。

相關文章

- 創建軟體包
- 軟體包降級
- pacman/軟體包簽名
- pacman/pacnew 與 pacsave
- pacman/Rosetta
- pacman/提示和技巧
- pacman/恢復本地資料庫
- FAQ
- 系統維護
- Arch 構建系統
- 官方倉庫
- Arch 用戶倉庫

Pacman軟體包管理器是 Arch Linux 發行版的一大亮點。它將一個簡單的二進制包格式和易用的構建系統結合了起來。Pacman的目標是簡化對軟體包的管理，無論軟體包是來自官方軟體倉庫還是用戶自己創建的軟體包。

Pacman 通過和主伺服器同步軟體包列表來保持系統是最新的。這種伺服器/客戶端模式可使得用戶使用簡單的命令，就能下載或安裝軟體包，並包含其所有必需的依賴包。

Pacman 用 C 語言編寫，並使用 bsdtar(1) tar 作為打包格式。

提示：pacman包 軟體包提供了如 makepkg 和 vercmp(8) 等工具。其它有用的工具如 pactree、checkupdates 等則在 pacman-contrib包 軟體包中（它曾是 pacman 的一部分）。運行 `pacman -Ql pacman | grep -E 'bin/.+'` 可查看完整的工具列表。

## 用法

以下只是 pacman 可以執行的操作的一小部分示例。要閱覽更多示例可參考 pacman(8)。

提示：對於以前使用過其他 Linux 發行版的用戶，Pacman Rosetta 這篇對比文章將大有幫助。

### 安裝軟體包

一個軟體包就是一個歸檔包，其中包含：

- 該軟體所有（編譯好的）文件，並按照每個文件的安裝位置儲存在一個與根目錄結構相同的目錄中
- 該軟體的元數據，例如軟體名稱、版本和依賴等
- 供 pacman 使用的其它描述性文件
- （可選）在安裝、升級、卸載時執行的安裝腳本

Arch 的軟體包管理器 pacman 可以安裝、更新和刪除這些軟體包。使用軟體包而不是自己編譯和安裝程序有很多好處：

- 輕鬆升級：pacman 會在更新可用時立即更新已安裝的軟體包
- 依賴檢查：pacman 會為你處理依賴問題，只需要指明程序（名），pacman 就會將它和它所需的所有其他程序都一起安裝。
- 乾淨卸載：pacman 持有軟體包包含的所有文件的列表。這樣一來，當你決定移除軟體包時，不會無意留下任何文件。

注意：

- 軟體包通常有可選依賴，它們為軟體提供額外的功能，但並不是軟體運行所必需的。安裝軟體時, pacman 會列出軟體包的可選依賴, 但這份列表不會記載在 `pacman.log` 中。請使用#查詢包資料庫命令查詢軟體包的可選依賴。
- 當你安裝軟體包以作為一些其他的軟體包的（可選）依賴時（即沒有明確要求安裝時），推薦使用 `--asdeps` 選項。請參閱#安裝原因一節了解詳細內容。

警告：在 Arch 上安裝軟體包時，請避免在還沒有更新系統前刷新同步軟體包列表（例如，當官方軟體倉庫不再提供某個軟體包時）。實際操作上，請使用 `pacman -Syu 軟體包名`, 而不要使用 `pacman -Sy 軟體包名`，因為後者可能會導致依賴問題。參見 系統維護#不支持部分升級一文和 BBS#89328 論壇討論。

#### 安裝指定的包

要安裝單個或者一系列軟體包（包含軟體包的依賴），請使用如下命令：

    # pacman -S 包名_1 包名_2 ...

要通過正則表達式安裝一系列軟體包（參見這個論壇帖子）：

    # pacman -S $(pacman -Ssq 包正则表达式)

有時軟體包有多個版本，放在不同的倉庫內（例如 extra 和 testing）。在以下示例中，要安裝 extra 倉庫的版本，需要在包名稱前定義倉庫名：

    # pacman -S extra/包名

要安裝多個含有相似名稱的軟體包，可以使用花括號擴展。例如：

    # pacman -S plasma-{desktop,mediacenter,nm}

可以多層擴展到需要的層次：

    # pacman -S plasma-{workspace{,-wallpapers},pa}

##### 虛包

虛擬軟體包是一個特殊的軟體包，它本身並不存在，但由一或多個其它軟體包提供。虛擬軟體包允許其它軟體包不以某一個特定的包為依賴，以應對有多個候選的情況。虛包不能用它們的名稱安裝，相反它們會在你安裝提供虛包的軟體包時被安裝到你的系統中。一個例子是dbus-units軟體包。

提示：當存在多個候選的情況下，可選包列表先按照`pacman.conf`中倉庫出現的順序排序，同一個倉庫有多個可選再按字母順序排序。

#### 安裝包組

一些包屬於一個可以同時安裝的軟體包組。例如，運行下面的命令

    $ pacman -S gnome

會提醒用戶選擇 `gnome` 內需要安裝的包。

有的包組包含大量的軟體包，有時用戶只需其中幾個。除了逐一鍵入序號外，pacman 還支持選擇或排除某個區間內的的軟體包：

    Enter a selection (default=all): 1-10 15

這將選中序號 1 至 10 和 15 的軟體包。而

    Enter a selection (default=all): ^5-8 ^2

將會選中除了序號 5 至 8 和 2 之外的所有軟體包。

想要查看哪些包屬於 gnome 組，運行：

    # pacman -Sg gnome

也可以訪問 https://archlinux.org/groups/ 查看可用的包組。

注意：如果列表中的包已經安裝在系統中，它會被重新安裝，即使它已經是最新的。可以用 `--needed` 選項覆蓋這種行為。

### 刪除軟體包

刪除單個軟體包，保留其全部已經安裝的依賴關係

    # pacman -R package_name

刪除指定軟體包，及其所有沒有被其他已安裝軟體包使用的依賴關係：

    # pacman -Rs package_name

警告：刪除類似 gnome 這樣的軟體包組時，將會忽略組中軟體包的安裝原因，因為實際操作上執行的是逐一刪除軟體組的每一個軟體，依賴軟體包的安裝原因不會被忽略。

上面這條命令在移除包含其他所需包的組時有時候會拒絕運行。這種情況下可以嘗試

    # pacman -Rsu package_name

要刪除軟體包和所有依賴這個軟體包的程序:

警告：此操作是遞歸的，請小心檢查，可能會一次刪除大量的軟體包。

    # pacman -Rsc package_name

要刪除一個被其他軟體包依賴的軟體包，但是不刪除依賴這個軟體包的其他軟體包：

警告：此操作有破壞系統的能力，應該儘量避免使用。詳情請看 避免某些 Pacman 命令。

    # pacman -Rdd package_name

pacman 刪除某些程序時會備份重要配置文件，在其後面加上*.pacsave擴展名。-n 選項可以避免備份這些文件：

    pacman -Rn package_name

注意：pacman 不會刪除軟體自己創建的文件（例如主目錄中的「點文件」不會被刪除。）

### 升級軟體包

警告：

- 建議用戶遵守系統維護#更新系統的指導，定期更新系統，並不盲目地執行這些命令。
- Arch 只支持系統完整升級，詳細參見系統維護#不支持部分升級和#安裝軟體包。

一個 pacman 命令就可以升級整個系統。花費的時間取決於系統有多老。這個命令會同步非本地(local)軟體倉庫並升級系統的軟體包：

    # pacman -Syu

### 查詢包資料庫

pacman 使用 `-Q` 參數查詢本地軟體包資料庫， `-S` 查詢同步資料庫，以及 `-F`查詢文件資料庫。要了解每個參數的子選項，分別參見 `pacman -Q --help`，`pacman -S --help`和`pacman -F --help`。

pacman 可以在包資料庫中查詢軟體包，查詢位置包含了軟體包的名字和描述：

    $ pacman -Ss string1 string2 ...

有時，`-s`的內置正則會匹配很多不需要的結果，所以應當指定僅搜索包名，而非描述或其他子段:

    $ pacman -Ss '^vim-'

要查詢已安裝的軟體包：

    $ pacman -Qs string1 string2 ...

按文件名查找軟體庫：

    $ pacman -F string1 string2 ...

顯示軟體包的詳盡的信息：

    $ pacman -Si package_name

查詢本地安裝包的詳細信息：

    $ pacman -Qi package_name

使用兩個 `-i` 將同時顯示備份文件和修改狀態：

    $ pacman -Qii package_name

獲取已安裝軟體包所包含文件路徑（比如用來查看軟體包提供了什麼可執行文件）：

    $ pacman -Ql package_name

查詢遠程庫中軟體包包含的文件：

    $ pacman -Fl package_name

檢查軟體包安裝的文件是否都存在：

    $ pacman -Qk package_name

兩個參數`k`將會執行一次更徹底的檢查。

查詢資料庫獲取某個文件屬於哪個軟體包：

    $ pacman -Qo /path/to/file_name

查詢文件屬於遠程資料庫中的哪個軟體包：

    $ pacman -F /path/to/file_name

要羅列所有不再作為依賴的軟體包(孤立orphans)：

    $ pacman -Qdt

要羅列所有明確安裝而且不被其它包依賴的軟體包：

    $ pacman -Qet

更多例子查看pacman tips。

#### Pactree

注意：pactree(8) 不再是 pacman包 的一部分。它現在在 pacman-contrib包 中。

要顯示軟體包的依賴樹：

    $ pactree package_name

要檢查一個已安裝的軟體包被哪些包依賴，可以將遞歸標識 `-r` 傳遞給 pactree，或者使用 pkgtoolsAUR 中的 whoneeds

#### 資料庫結構

pacman 資料庫通常位於 `/var/lib/pacman/sync`。對於每一個在 `/etc/pacman.conf` 中指定的軟體倉庫， 這裡都有一個一致的資料庫。資料庫文件夾裡每個 tar.gz 文件都包含著一個倉庫的軟體包信息。例如 which包 包:

    $ tree which-2.21-5

    which-2.21-5
    |-- desc

這個 `depends` 項列出了該軟體的依賴包， 而 `desc` 有該包的介紹，例如文件大小和MD5值 。

### 清理軟體包緩存

pacman 將下載的軟體包保存在 `/var/cache/pacman/pkg/` 並且不會自動移除舊的和未安裝版本的軟體包。這樣做有一些好處：

1. 這樣允許降級軟體包而不需要通過其他方式提取舊版本，例如 Arch Linux Archive.
2. 被卸載的軟體包可以輕易地直接從緩存文件夾重新安裝，不需要重新從軟體倉庫下載。

然而，需要定期手動清理緩存來避免該文件夾無限制增大。

pacman-contrib包 提供的 paccache(8) 腳本默認會刪除所有緩存的版本和已卸載的軟體包，除了最近的3個會被保留：

    # paccache -r

啟用和啟動 `paccache.timer`來每周刪除不使用的包。

提示：可以使用#鉤子自動執行清理，安裝 paccache-hookAUR 並參考[1]。

也可以自己設置保留最近幾個版本：

    # paccache -rk1

添加`-u`/`--uninstalled`開關來限制paccache的行為只作用於卸載的包。例如清理所有卸載的包的緩存版本，可以用以下命令:

    # paccache -ruk0

更多參數參見`paccache -h`。

pacman也有一些內建參數用於清除緩存和那些不再在`/etc/pacman.conf`配置文件中列出的軟體倉庫殘留資料庫文件。然而pacman並不提供保留一定數量的過去版本的功能，因此它比paccache的默認選項更加激進。

要刪除目前沒有安裝的所有緩存的包，和沒有被使用的同步資料庫，執行：

    # pacman -Sc

要刪除緩存中的全部文件，使用兩次`-c`開關。這是最為激進的方式，將會清空緩存文件夾：

    # pacman -Scc

警告：應當避免從緩存中刪除所有過去版本和卸載的包，除非需要更多磁碟空間。這樣會導致無法降級或重新安裝軟體包時需要再次下載。

pkgcachecleanAUR以及pacleanerAUR是兩個進一步清理緩存的替代工具

### 其它命令

升級系統時安裝其他軟體包：

    # pacman -Syu package_name1 package_name2 ...

下載包而不安裝它：

    # pacman -Sw package_name

安裝一個本地包(不從源裡下載）：

    # pacman -U /path/to/package/package_name-version.pkg.tar.zst

要將本地包保存至緩存，可執行：

    # pacman -U file:///path/to/package/package_name-version.pkg.tar.zst

安裝一個遠程包（不在 pacman 配置的源裡面）：

    # pacman -U http://www.example.com/repo/example.pkg.tar.zst

#### 查看軟體變動

pacman 會列出需要安裝和刪除的軟體，並在執行動作前要求需要的權限。

要抑制`-S`，`-U` 和 `-R`，的動作並列出涉及該動作相關軟體的列表，可以使用`--print`或縮寫`-p`。

可以添加`--print-format` 參數將輸出格式化，例如使用`--print-format %n`將返回不帶有版本號的列表。

### 安裝原因

pacman 資料庫將軟體包按照安裝的原因分為兩類：

- 顯式安裝：那些真正地被傳遞給通用pacman`-S`和`-U`命令的包；
- 依賴：那些雖然（一般）從未被傳遞給pacman安裝命令，但由於被其它顯式安裝的包需要從而被隱式安裝的包

當安裝軟體包時，可以把安裝原因強制設為依賴:

    # pacman -S --asdeps package_name

該命令使用的原因通常是顯式安裝的包可能會提供可選安裝包，這些包提供了非必須功能，可供用戶自由選擇。

提示：用`--asdeps`安裝可選依賴將確保如果你移除孤立包，pacman將會一同移除按照上述方法指定安裝的可選依賴。

但是重新安裝該軟體包，當前安裝原因默認會被保留。

顯式安裝的軟體包列表可用`pacman -Qe`獲取, 設置為依賴的軟體包可用`pacman -Qd`獲取。

改變某個已安裝軟體包的安裝原因，可以執行：

    # pacman -D --asdeps package_name

反過來的對應參數`--asexplicit`

注意：在升級時使用`--asdeps`和`--asexplicit`選項，例如`pacman -Syu package_name --asdeps`，是不被推薦的。這會導致不僅改變要被安裝的軟體包的安裝原因，也會改變被升級的軟體包的安裝原因。

### 查詢一個包含具體文件的包名

同步文件資料庫:

    # pacman -Fy

查詢包含某個文件的包名，比如:

    # pacman -F pacman
    core/pacman 5.0.1-4
        usr/bin/pacman
        usr/share/bash-completion/completions/pacman
    extra/xscreensaver 5.36-1
        usr/lib/xscreensaver/pacman

提示： 可以啟用/啟動 `pacman-filesdb-refresh.timer`（該定時器在pacman-contrib包中）來每周同步文件信息資料庫。

如果需要高級功能請安裝 pkgfile，它使用一個單獨的資料庫來保存文件和它們所關聯的軟體包的信息。

### 安裝/更新/刪除 軟體包時發生了什麼

動作成功執行時，事務包含五大步驟和事務鉤子程序:

1. 如果資料庫未被鎖定，初始化事務
2. 確認事務中要添加或刪除的軟體包
3. 準備事務，根據參數，對同步資料庫、軟體包和依賴關係進行校驗
4. 提交事務:
   1. 如果需要，下載軟體包 (`_alpm_sync_load`)
   2. 如果有可以執行的 pacman `PreTransaction` 鉤子，執行這些鉤子.
   3. 被替換、出現衝突或被指定刪除的軟體包將會被刪除
   4. 如果需要添加軟體包，每個軟體包都會執行提交
      1. 如果有安裝腳本，執行 `pre_install` 函數(更新時執行 `pre_upgrade`，刪除時執行 `pre_remove`).
      2. pacman 刪除軟體包之前版本的所有文件 (在更新或刪除軟體包時)。配置文件將會被保留 (請參閱 Pacman/Pacnew and Pacsave).
      3. pacman 將軟體包文件解壓到系統(安裝或升級軟體包時). 會覆蓋舊的已被手動修改的配置文件時，配置文件會命名為 (.pacnew).
      4. 如果軟體包有安裝腳本，執行 `post_install` 函數(更新時執行 `post_upgrade`，刪除時執行 `post_remove`).
   5. 如果pacman `PostTransaction` 鉤子可執行，執行這些鉤子.
5. 釋放事務及事務資源 (例如，資料庫鎖)

## 配置

pacman 的配置文件位於`/etc/pacman.conf`。 man pacman.conf 可以查看配置文件的進一步信息。

### 通用選項

通用選項都在`[options]`段。閱讀 man 手冊或者查看默認的 pacman.conf 可以獲得有關信息和用法。

### 升級前對比版本

要查看舊版和新版的有效安裝包，請取消`/etc/pacman.conf`中"VerbosePkgLists"的注釋。修改後的`pacman -Syu`輸出如下：

    Package (6)             Old Version  New Version  Net Change  Download Size

    extra/libmariadbclient  10.1.9-4     10.1.10-1      0.03 MiB       4.35 MiB
    extra/libpng            1.6.19-1     1.6.20-1       0.00 MiB       0.23 MiB
    extra/mariadb           10.1.9-4     10.1.10-1      0.26 MiB      13.80 MiB

#### 啟用並行下載

Pacman 6.0 增加了並行下載選項，將 `/etc/pacman.conf` 中 `[options]` 選項 `ParallelDownloads` 設置成正整數，例如 `5`，將會同時下載 5 個軟體包，如果未設置此選項，軟體包將會被依次下載。

#### 在升級時跳過軟體包

警告：在跳過軟體包時要小心，因為部分升級不受支持

要想在升級系統時跳過特定的軟體包，用像如下的命令指明：

    IgnorePkg=linux

多軟體包可以用空格隔開，或者用另外的`IgnorePkg`行。也可使用 glob 模式。如果只打算忽略一次升級，可以使用 `--ignore` 選項，這時使用逗號隔開的列表。

忽略了的軟體包依然可通過 `pacman -S` 升級。這種情況下pacman會提醒你這些軟體包已經被包含在`IgnorePkg`聲明中。

#### 在升級時跳過軟體包組

警告：在跳過軟體包時要小心，因為部分升級不受支持

和軟體包一樣，也可以不升級某個軟體包組：

    IgnoreGroup = gnome

#### 在升級時跳過文件

所有在`NoUpgrade`指令中列出的文件都會在軟體包被安裝/升級時不會被更改，並且新文件會以帶有.pacnew後綴名的形式安裝

    NoUpgrade=path/to/file

    存在多个跳过文件也可以像这样指定：

    NoUpgrade=path/to/file1 path/to/file2

注意：這個路徑指軟體包中的文件，所以不要包括開頭的斜線。

#### 在安裝時跳過文件

要總是跳過某些文件夾的安裝，可以將它們放到 `NoExtract` 中，例如不想安裝 systemd 模塊：

    NoExtract=usr/lib/systemd/system/*

後面的規則覆蓋前面的規則，加上 `!` 可以取消跳過效果。

提示：pacman會在更新locales已經被localepurge或者bleachbit清除的包時發出警告。注釋掉`pacman.conf`中的`CheckSpace`參數能夠抑制這種警告，但是要注意space-check功能將會對所有軟體包禁用。

### 保留多個配置文件

如果你有多個配置文件（比如，主配置和啟用了測試倉庫的配置文件），需要共享一些設置，你可以在配置文件中使用`Include`選項，例如：

    Include = /path/to/common/settings

`/path/to/common/settings`文件中是兩個配置文件共享的相同配置。

### 鉤子

pacman可以在處理前後，運行`/usr/share/libalpm/hooks/`文件夾下的hooks，更多的hooks文件夾可以通過`HookDir`選項在`pacman.conf`中指明，默認`/etc/pacman.d/hooks`。Hook文件必須以.hook為後綴。Pacman hooks不是交互式的。

pacman hooks用於，比如說，和`systemd-sysusers`和`systemd-tmpfiles`結合來在安裝包時自動創建系統用戶和文件。例如，tomcat8包指明它想要創建一個叫做`tomcat8`的系統用戶和一些屬於該用戶的文件。當pacman確定tomcat8包包含文件指明用戶和臨時文件時，pacman hooks `systemd-sysusers.hook`和`systemd-tmpfiles.hook`喚起`systemd-sysusers`和`systemd-tmpfiles`。

有關 alpm hooks 的更多信息，參見alpm-hooks(5)。

### 軟體倉庫

除了特殊的通用選項節, 每個`pacman.conf`中的`[section]`都定義了一個使用的軟體包倉庫，倉庫是多個軟體包的邏輯上的集合，他們物理上存儲在一個或多個伺服器：這也是為什麼每一個伺服器都叫做這個倉庫的鏡像。

倉庫區分為官方倉庫與非官方倉庫。配置文件中倉庫的順序十分重要；當幾個倉庫出現同名安裝包，不管版本號如何，pacman將使用配置文件中排前的倉庫。要在添加後使用某個倉庫，你需要先升級整個系統

每個倉庫節都可以直接指定鏡像列表或者`Include`引用其他的文件：例如，官方鏡像引用了`/etc/pacman.d/mirrorlist/`。具體查看Mirrors。

### 軟體包的緩存目錄

在`pacman.conf`通用選項節，`CacheDir`指定了Pacman下載的安裝包緩存位置(如果未設置，默認位置為 `/var/cache/pacman/pkg/`)。

即使只保留最新版本的安裝包，緩存目錄大小仍然有可能隨著時間增長。

如果要將緩存目錄移動到更方便的地方，只需要完成下列方法中的任意一個：

- 在`pacman.conf`通用選項節，設置`CacheDir`為要使用的緩存目錄，並確保目錄以"/"結尾。推薦使用該方法.
- 將一個專用分區掛載到默認緩存點`/var/cache/pacman/pkg/`，例如使用Btrfs 子卷。
- 將一個目錄與 `/var/cache/pacman/pkg/`綁定掛載。

警告：不要使用符號連結 將 `/var/cache/pacman/pkg/` 目錄指向其它位置。 這會導致pacman出現異常，特別是當pacman嘗試升級自己時。

### 軟體包的安全性

pacman 支持軟體包簽名，會為軟體包提供額外的安全性。默認配置，`SigLevel = Required DatabaseOptional` 將啟用全局簽名驗證，但會被每個軟體倉庫的 `SigLevel` 行所覆蓋。有關軟體包簽名和簽名驗證的更多細節，參見 pacman-key。

## 疑難解答

### "Failed to commit transaction (conflicting files)" 錯誤

如果碰到如下錯誤：[2]

    error: could not prepare transaction
    error: failed to commit transaction (conflicting files)
    package: /path/to/file exists in filesystem
    Errors occurred, no packages were upgraded.

這是因為 pacman 檢測到文件衝突，而且按照設計，pacman 不會覆蓋文件。這是設計功能，不是缺陷。

這個問題通常很容易解決（當然你首先應該嘗試搞清楚這些文件是怎麼變成這樣的）。一個安全的方式是，首先檢查是否有另一個軟體包提供了這個文件 (`pacman -Qo /path/to/file`)。如果文件被另一個軟體包所有，請報告問題。如果不是其它軟體包提供，將 'exists in filesystem' 的文件重命名並重新運行update命令。如果一切順利，可以刪掉這個文件。

如果你手動安裝了一個軟體，沒有通過pacman，例如用`make install`，你必須將軟體連同它的全部文件一起移除/卸載。參見Pacman/提示和技巧#查找不屬於任何軟體包的文件。

每一個安裝的軟體包都會提供一個 `/var/lib/pacman/local/$package-$version/files` 文件，包含此軟體包的元數據。如果文件損壞或者丟失，將會導致升級時出現`file exists in filesystem` 錯誤。此錯誤通常只會影響一個軟體包，除了手動刪除或移動所有的問題文件，你也可以顯式地使用`pacman -S --overwrite glob package`讓 pacman 強制覆蓋匹配`glob`的文件。

警告：儘量避免使用`--overwrite`開關。參見System maintenance#避免某些 pacman 命令

### "Failed to commit transaction (invalid or corrupted package)" 錯誤

看看`/var/cache/pacman/pkg`中是否有`*.part`結尾的文件，它們是沒有完全下載的文件，刪除它們並重新執行更新。這些程序一般是自定義的`XferCommand` 下載命令造成的。

    # find /var/cache/pacman/pkg/ -iname "*.part" -delete

同樣的錯誤也可能是因為archlinux-keyring過期所致，阻止了pacman驗證簽名。詳情見Pacman/Package signing#Upgrade system regularly以修復並避免在未來遇到同樣問題。

### "Failed to init transaction (unable to lock database)" 錯誤

pacman 在改變軟體包資料庫前，比如安裝軟體包時，會創建一個文件鎖 `/var/lib/pacman/db.lck`。這會阻止其他 pacman 實例在同一時間修改軟體包資料庫。

如果 pacman 在更新資料庫時被打斷，舊鎖可能保留下來。如果確認沒有 pacman 實例在運行，那麼刪掉文件鎖：

    # rm /var/lib/pacman/db.lck

提示：以root身份運行`fuser /var/lib/pacman/db.lck`可以確認是否有其它進程仍在使用它。

### 安裝時無法獲取軟體包

錯誤內容包含：`Not found in sync db`, `Target not found` 或 `Failed retrieving file`.

首先確認軟體包確實存在（並注意錯別字）。如果確認軟體包存在，可能本地資料庫過時了或者軟體倉庫沒有配置好，試試 `pacman -Syyu` 強制資料庫更新和升級。

也有可能包含該軟體包的軟體倉庫沒有啟動。例如，該軟體包可能在 multilib 倉庫裡，但該倉庫沒有在 pacman.conf 中啟用。

參閱常見問題#Q) 在官方倉庫中，為什麼只為每個共享連結庫提供一個版本？.

### pacman 更新時崩潰

如果 pacman 在刪除、重新安裝或更新軟體包時 "資料庫寫入" 出錯：

1. 從 Arch 安裝媒體啟動，最好用最新的安裝媒體
2. 掛載根文件系統，例如以 root 身份`mount /dev/sdaX /mnt`，通過 `df -h` 確認根文件目錄包含足夠的空間
3. 同樣掛載 proc, sys 和 dev 文件系統：`mount -t proc proc /mnt/proc; mount --rbind /sys /mnt/sys; mount --rbind /dev /mnt/dev`
4. 如果系統使用默認的資料庫目錄位置，可以通過 root 用戶執行下面命令`pacman --root=/mnt --cachedir=/mnt/var/cache/pacman/pkg -Syu`來更新系統的 pacman 資料庫。
5. 如果無法更新，可以重新安裝所有軟體包。
6. 更新之後，可以通過下面命令確認是否還存在損壞的包：`find /mnt/usr/lib -size 0`
7. 通過`pacman --root /mnt --cachedir=/mnt/var/cache/pacman/pkg -S package`重新安裝依然損壞的軟體包

#### pacman: command not found

如果`/var/cache/pacman/pkg`是一個符號連結，pacman在升級自身時會創建該目錄並移除符號連結，這會導致升級失敗，並產生`/usr/bin/pacman` 與其它 pacman包包中內容丟失的後果。

永遠不要為`/var/cache/pacman/pkg`創建軟連接，因為該目錄受pacman控制。使用`CacheDir`選項或通過綁定掛載。參見#軟體包的緩存目錄。

如果你已經遇到這個問題，你可以手動提取安裝包中`/usr`的內容恢復，並重新安裝pacman。詳情見FS#73306和論壇相關話題

### 手動重新安裝 pacman

#### 使用 pacman-static

pacman-staticAUR是pacman的靜態編譯版本，因此系統中的庫文件失效時依然可以運行它。當部分升級後pacman無法運行，靜態編譯版本就能夠派上用場。

置頂評論和PKGBUILD提供了直接下載二進制文件的方法，可以用於重新安裝pacman或在部分升級情況下升級整個系統。

#### 使用外部 pacman

如果`pacman-static`也無法使用，考慮使用外部pacman。 最簡單的辦法是使用archiso並指定`--sysroot`或`--root`參數到系統操作的掛載點。參見Chroot#使用 arch-chroot來掛載`--sysroot`參數需要的文件系統。

#### 手動提取

警告：這種方式極其容易破壞你的系統，把它變得更糟。這個方式只是作為最後的措施，以防萬一#pacman 更新時崩潰不起作用

即使 pacman 嚴重損壞，你仍可以手動修復它，這需要下載最新的包並把它們解壓到正確的目錄。大致步驟如下：

1. 確定要安裝的pacman包依賴項
2. 從你選擇的mirror下載每個包
3. 把每個包解壓到 root
4. 使用`pacman -S --overwrite`重新安裝這些包來更新相應的軟體包資料庫
5. 進行完整系統更新

如果你擁有一個健康的 Arch 系統，你可以這樣查看依賴項的完整列表：

    $ pacman -Q $(pactree -u pacman)

但是依據你遇到的問題，你可能只需要更新其中的幾個。解壓一個包的示例是：

    # tar -xvpwf package.tar.zst -C / --exclude .PKGINFO --exclude .INSTALL --exclude .MTREE --exclude .BUILDINFO

注意`w`參數表示交互模式。以非交互方式運行是非常冒險的，因為你可能就此覆蓋了一個重要文件。你也要注意以正確的順序解壓軟體包（例如先解壓依賴）。 這個帖子包含了一些這個過程的例子，這些例子中只有少量pacman依賴項損壞。

### 升級系統重啟後，出現"unable to find root device"錯誤，無法登錄

很有可能 initramfs 在內核升級時損壞（例如由錯誤地使用 pacman 的 `--overwrite` 選項導致）。有兩個選擇；首先嘗試 Fallback啟動項。

提示：萬一你刪除了 Fallback 啟動項，你總可以在啟動加載器菜單顯示出來的時候按`Tab`鍵（對於 Syslinux）或者按`e`鍵（對於 GRUB 或者 systemd-boot），將它重命名為`initramfs-linux-fallback.img`然後按`Enter`或者`b`（取決於你的啟動加載器以新參數啟動的方式）

一旦系統啟動，從控制台或終端（為備用linux包內核）運行這條命令來重建 initramfs 映像：

    # mkinitcpio -p linux

如果上面方法不行，從一個最新的 Arch 發行版本（CD/DVD 或者 U盤），分別掛載你的根目錄和啟動分區到`/mnt`和`/mnt/boot`，然後用 arch-chroot chroot：

    # arch-chroot /mnt
    # pacman -Syu mkinitcpio systemd linux

注意：

- 如果你沒有一個當前的發行或者你只有某些其他的 "live" Linux 發行版，你可以用老式的方法chroot。顯然，這種方式比簡單地運行`arch-chroot`腳本需要更多的輸入
- 如果 pacman 伴隨`Could not resolve host`運行失敗，請檢查你的網絡連接
- 如果無法進入 arch-chroot 或 chroot 環境，但是需要重新安裝軟體包，可以使用 `pacman --sysroot /mnt -Syu foo bar` 從而在你的根分區下使用 pacman

重新安裝內核(linux包 軟體包)將會自動運行 `mkinitcpio -p linux` 重新生成 initramfs 鏡像，不需要單獨生成。

之後建議執行 `exit`, `umount /mnt/{boot,}` 然後 `reboot`.

### 'warning: current locale is invalid; using default "C" locale' 錯誤

錯誤信息已經很明確了，locale 設置不正確，請閱讀Locale進行設置。

### Pacman 不使用我的代理設置

正確設置環境變量（`$http_proxy`, `$ftp_proxy` 等）。如果使用 sudo，需要讓 sudo 將這些變量傳遞給 pacman。另外，在更新密鑰前確保`/etc/pacman.d/gnupg/dirmngr.conf`路徑的 dirmngr配置文件`honor-http-proxy`變量設置正確。

### 如何重裝所有包並保留安裝和依賴信息？

重裝所有軟體包：`pacman -S $(pacman -Qnq)`（`-S` 選項會保留安裝緣由）。

接著需要重裝外來包（不在官方倉庫裡的軟體包）。外來包可通過`pacman -Qmq`查看。

### "Cannot open shared object file" 錯誤

有可能是前一次 pacman 事務中刪除或者損壞了 pacman 自身需要的一些共享庫。

要修復這種情況，你需要手動解壓那些共享庫文件到文件系統中合適的地方。首先請查明哪個包中包含有所需的庫文件，然後在 pacman 緩存中 (`/var/cache/pacman/pkg/`) 找到對應的包。解壓出需要的庫文件到文件系統的對應位置，如此可以繼續使用 pacman 。

之後需要重新安裝損壞的軟體包。注意你可能需要使用 `--overwrite` 選項覆蓋掉你剛剛解壓出的系統文件，因為 pacman 可能沒有跟蹤到對應的文件信息。 pacman 隨後會使用包中的文件正確替換掉共享庫文件。如此能修好您的 pacman ，然後請繼續更新系統中剩下的軟體包。

### 軟體包下載停滯

一些網絡問題可能會報告阻止了 pacman 更新和同步倉庫。[3] [4] 在實體機中安裝 Arch Linux 時，這些問題已經通過替換默認的 pacman 文件下載器得到了解決 (更多細節請參閱 Pacman/提示和技巧#性能 ) 。當在 VirtualBox 中安裝 Arch Linux 作為客戶作業系統時，這個問題也通過在主機屬性中使用主機界面而不是 NAT 來解決。

### 無法從鏡像伺服器獲取 'core.db'

如果從正確的鏡像伺服器收到此錯誤，請換一個域名解析伺服器。

### error: 'local-package.pkg.tar': permission denied

如果你想要在一個 sshfs 上使用`pacman -U`安裝軟體包並遇到了這個錯誤，將包移動到本地目錄，再試一次。

### error: could not determine cachedir mount point /var/cache/pacman/pkg

在 chroot 環境中執行 `pacman -Syu` 可能發生此錯誤:

    error: could not determine cachedir mount point /var/cache/pacman/pkg
    error: failed to commit transaction (not enough free disk space)

通常是因為進入 chroot 時，進入的目錄不是掛載點。解決方法請參考從現有 Linux 發行版安裝 Arch Linux#下載基本工具， arch-chroot(8) 解釋問題的原因，並提供了一個通過 bind mount 解決問題的方法。

### error: GPGME error: No data

如果你無法更新包，並遇到了該問題，嘗試

`rm -r /var/lib/pacman/sync/`

後再次更新。

如果刪除sync中的同步文件不能解決問題，請通過`file /var/lib/pacman/sync/*`檢查同步文件是否為`gzip compressed data`，使用路由或代理可能會損壞下載的文件。

如果同步文件是正確的類型，那麼問題可能出在鏡像源上。使用`pacman-conf -r core`和`pacman-conf -r extra`查詢使用的鏡像源，將命令輸出的第一個URL粘貼到瀏覽器訪問，檢查返回的文件。如果返回有問題，在{ic|/etc/pacman.d/mirrorlist}}裡修改為其他可用鏡像源。

## 另請參見

- Pacman 主頁
- libalpm(3)
- pacman(8)
- pacman.conf(5)
- repo-add(8)
- AUR

分類：​

- 包管理器
- Arch 項目

pacman
新增話題