首頁 > 軟體

Pacman Hooks 簡介

2020-06-16 17:40:42

Pacman 5.0 帶來了 Hooks 支援,但在大規模應用前,我們留出了一個多月的時間來讓使用者先升級到 Pacman 5.0(因為同時升級 pacman 和有定義 hooks 的包會導致無法正常執行這些 hooks)。現在距離 Hooks 正式投入使用已經過去了一個月,我覺得是時候介紹一下 Hooks 和如何使用它了。

先來看一個簡單的 Hook:

[Trigger]
Type = File
Operation = Install
Operation = Upgrade
Target = usr/lib/tmpfiles.d/*.conf

[Action]
Description = Creating temporary files...
When = PostTransaction
Exec = /bin/sh -c 'while read -r f; do /usr/bin/systemd-tmpfiles --create "/$f"; done'
NeedsTargets

這個 Hook 的作用是:當檢測到安裝或更新的包檔案中存在 usr/lib/tmpfiles.d/*.conf 時,在更新後對每個檔案呼叫 systemd-tmpfiles --create 方法。前面的檢測部分定義在 [Trigger] 部分,後面執行的操作定義在 [Action] 部分。下面我們分別了解一下這兩部分。

一、[Trigger] 部分

首先需要了解的是可以用於觸發的條件類別(Type)。上面的例子裡使用了檔案(File),即當操作中的包中存在對應檔案時觸發。另一個可選的 Type 是軟體包名(Package),即直接匹配操作中的包名。

接下來,操作(Operation)選項限制了對軟體包的操作類別。可以選擇的操作有安裝(Install)、更新(Upgrade)和刪除(Remove)。一個 Hook 需要在多種操作執行時,如例子中那樣寫成多行即可。常用的組合有三種全部寫上(更新快取、資料庫等)、寫 Install+Upgrade(執行安裝時的一次性操作)及與之對應的 Upgrade+Remove(解除安裝時的一次性操作)。

最後,我們需要定義具體的目標(Target)。如果目標是檔案,這裡需要寫其相對根目錄的完整路徑,但需要去掉開頭的 / 字元。萬用字元(*、?)可以使用,具體匹配時會使用 fnmatch 方法。同樣的,在一個 Hook 中可以定義多個目標,類似例子中的 Operation 那樣寫成多行即可。

二、[Action] 部分

先看看 Hooks 的執行時機:

可以看到,有兩類明顯不同的 Hooks: Pre-transaction Hooks 和 Post-transaction Hooks。

Pre-transaction Hook 在具體操作發生前執行,此時待升級的軟體包還未被升級,待刪除的軟體包還未被刪除,還可以讓它們來綻放最後的光芒。因此,這種 Hook 通常和上面 [Trigger] 部分的 Upgrade、Remove 操作搭配使用。如 gconf 包的 gconf-remove Hook,會在 gconf schema 被刪除前呼叫 gconfpkg --uninstall 命令來解除安裝對應的 schema。

Post-transaction Hook 則與它相反,是在操作完成後執行。如上面的 tmpfiles Hook。

這兩種不同的型別被定義在 When 選項中,分別寫作 PreTransactionPostTransaction

Description 選項僅包含一個供人類閱讀的描述資訊。目前的通用做法是用動詞進 行時作為開頭,英文省略號作為結束。顯示在終端中會成為這樣的效果:

(1/1) Creating temporary files...

Exec 選項定義了具體執行的命令。和上面 Target 選項不同,這裡不但需要寫出待執行命令的完整路徑,還需要保留最前方的 / 字元。如果在命令中需要用到前面 Trigger 得到的具體結果(如上面例子),你還需要在 [Action] 部分寫一行 NeedsTargets 來讓被匹配到的目標成為 Exec 選項的 stdin 輸入,一行一個。值得注意的是如果匹配到的目標是檔案,我們在對它進行操作前也需要補上最前方的 / 字元,如上面例子中使用的 "/$f"

此外,[Action] 部分還有一些其他選項:

  • Depends 選項:定義 Hook 執行時需要的依賴。如果觸發時對應依賴關係不滿足,Hook 會拒絕執行。可以定義多次。
  • AbortOnFail 選項:當 Hook 執行失敗時終止整個操作。這個僅對 Pre-transaction Hook 有效,畢竟 Post-transaction 發生在操作之後,定義這個選項沒有意義。這個選項和 NeedsTargets 選項一樣不需要任何引數。

總結

姍姍來遲的 Hooks 功能替代了許多原本在 .install 檔案中定義的操作,大幅減少了在每個包中重複寫這些操作的困擾,也節省了大量重複執行操作浪費的時間。目前有很多常見操作已經採用了 Hooks,但還有很多仍然在完善中。如果你在用的 AUR 包還沒有採用這些 Hooks,請不要猶豫,趕快改改拍在維護者臉上吧!

關於哪些通用操作已經採用了 Hooks,可以參考這個 Wiki 頁面。此外,如果想找更多 Hooks 的例子來研究,可以開啟原生的 /usr/share/libalpm/hooks/ 目錄,你已經安裝的 Hooks 都在這裡。

參考資料:上文中的 Wiki 頁面,以及 pacman 原始碼

Felix Yan

本文永久更新連結地址http://www.linuxidc.com/Linux/2016-05/131856.htm


IT145.com E-mail:sddin#qq.com