22 update-alternatives
:管理指令和檔案的多個版本 #
系統上往往會安裝同一個工具的多個版本。為了讓管理員有選擇,以及能一起安裝和使用多個不同的版本,替代項系統提供了以一致的方式管理此類版本的功能。
22.1 綜覽 #
在 SUSE Linux Enterprise Desktop 上,有幾個程式執行的是相同或類似的任務。例如,如果系統上既安裝了 Java 1.7,也安裝了 Java 1.8,則會從 RPM 套件中呼叫替代項系統指令碼 (update-alternatives
)。替代項系統預設將參考版本 1.8:版本越高,優先程度就越高。不過,管理員可以變更該預設設定,並可將一般名稱指向版本 1.7。
本章使用了下列術語:
- 管理目錄
預設的
/var/lib/rpm/alternatives
目錄,其中包含有關替代項目前狀態的資訊。- 替代方案
檔案系統中某個特定檔案的名稱,可使用替代項系統透過一般名稱存取。
- 替代項目錄
包含符號連結的預設
/etc/alternatives
目錄。- 一般名稱
該名稱 (例如
/usr/bin/edit
) 參考可透過替代項系統使用的多個檔案中的一個。- 連結群組
一組相關的符號連結,可做為一個群組更新。
- 主連結
連結群組中用於確定如何設定群組中其他連結的連結。
- 從屬連結
連結群組中受主連結控制的連結。
- 符號連結 (symlink)
在同一檔案系統中做為另一個檔案的參考的檔案。替代項系統使用替代項目錄中的符號連結,在一個檔案的各個版本之間切換。
管理員可透過
update-alternatives
指令修改替代項目錄中的符號連結。
替代項系統提供 update-alternatives
指令,用來建立、移除、維護和顯示有關符號連結的資訊。雖然這些符號連結通常指向指令,但它們也可以指向 JAR 歸檔、手冊頁及其他檔案。本章中的範例使用了指令和手冊頁,但它們也適用於其他檔案類型。
替代項系統使用替代項目錄來收集指向可能的替代項的連結。安裝包含替代項的新套件時,會將新的替代項新增至系統。是否將新套件的替代項選為預設值取決於它的優先程度和設定的模式。版本較高的套件優先程度也較高。替代項系統可以在兩種模式下運作:
自動模式: 在此模式下,替代項系統會確保群組中的連結指向適合群組且優先程度最高的替代項。
手動模式: 在此模式下,替代項系統不會對系統管理員的設定進行任何變更。
例如,在替代項系統中,java
指令具有以下連結階層:
22.2 使用案例 #
預設從 RPM 套件中呼叫 update-alternatives
指令碼。安裝或移除一個套件時,該指令碼會處理該套件所有的符號連結。不過,您可以從指令列中手動執行該指令碼,以便:
顯示一般名稱的目前替代項。
變更替代項的預設值。
為替代項建立一組相關的檔案。
22.3 取得替代項的綜覽 #
若要取回所有已設定替代項的名稱,請使用:
>
ls /var/lib/alternatives
若要取得所有已設定替代項的綜覽及其值,請使用
>
sudo
update-alternatives --get-selections
asadmin auto /usr/bin/asadmin-2.7 awk auto /usr/bin/gawk chardetect auto /usr/bin/chardetect-3.6 dbus-launch auto /usr/bin/dbus-launch.x11 default-displaymanager auto /usr/lib/X11/displaymanagers/gdm [...]
22.4 檢視關於特定替代項的詳細資料 #
檢查替代項最簡單的方法就是查看指令的符號連結。例如,若要確定 java
指令參考的是什麼,請使用以下指令:
>
readlink --canonicalize /usr/bin/java
/usr/lib64/jvm/jre-10-openjdk/bin/java
如果您看到相同的路徑 (在本範例中為 /usr/bin/java
),則說明此指令沒有替代項。
若要檢視全部的替代項 (包括從屬連結),請使用 --display
選項:
>
sudo
update-alternatives --display java
java - auto mode link best version is /usr/lib64/jvm/jre-1.8.0-openjdk/bin/java link currently points to /usr/lib64/jvm/jre-1.8.0-openjdk/bin/java link java is /usr/bin/java slave java.1.gz is /usr/share/man/man1/java.1.gz slave jre is /usr/lib64/jvm/jre slave jre_exports is /usr/lib64/jvm-exports/jre slave keytool is /usr/bin/keytool slave keytool.1.gz is /usr/share/man/man1/keytool.1.gz slave orbd is /usr/bin/orbd slave orbd.1.gz is /usr/share/man/man1/orbd.1.gz [...]
22.5 設定替代項的預設版本 #
/usr/bin
中的指令預設會參考優先程度最高的替代項目錄。例如,java
指令預設會顯示下面的版本號碼:
>
java -version
openjdk version "10.0.1" 2018-04-17 OpenJDK Runtime Environment (build 10.0.1+10-suse-lp150.1.11-x8664) OpenJDK 64-Bit Server VM (build 10.0.1+10-suse-lp150.1.11-x8664, mixed mode)
若要將預設 java
指令變更為參考先前的版本,請執行:
>
sudo
update-alternatives --config java
root's password: There are 2 choices for the alternative java (providing /usr/bin/java). Selection Path Priority Status ------------------------------------------------------------ * 0 /usr/lib64/jvm/jre-10-openjdk/bin/java 2005 auto mode 1 /usr/lib64/jvm/jre-1.8.0-openjdk/bin/java 1805 manual mode 2 /usr/lib64/jvm/jre-10-openjdk/bin/java 2005 manual mode 3 /usr/lib64/jvm/jre-11-openjdk/bin/java 0 manual mode Press <enter> to keep the current choice[*], or type selection number:
根據您的系統和安裝的版本而定,具體的 Java 版本號碼會有所不同。選取 1
之後,java
會顯示下面的版本號碼:
>
java -version
java version "1.8.0_171" OpenJDK Runtime Environment (IcedTea 3.8.0) (build 1.8.0_171-b11 suse-lp150.2.3.1-x86_64) OpenJDK 64-Bit Server VM (build 25.171-b11, mixed mode)
另外,請記住以下幾點:
在手動模式下安裝另一個 Java 版本時,替代項系統既不會變更連結,也不會變更一般名稱。
在自動模式下安裝另一個 Java 版本時,替代項系統會變更 Java 主連結及所有從屬連結 (如第 22.4 節 「檢視關於特定替代項的詳細資料」中所示)。若要檢查主/從關係,請使用:
>
sudo
update-alternatives --display java
22.6 安裝自訂替代項 #
本節介紹如何在系統上設定自訂替代項。
不要安裝 python3 的自訂替代項。/usr/bin/python3
沒有更新替代項,並且永遠指向特定的已測試版本。建立指向其他版本 (如 python 3.11) 的自訂 python3 替代項會損毀相依的系統工具。
範例做了以下假設:
具有類似功能的指令碼有兩個,分別是
foo-2
和foo-3
。這些指令碼儲存在
/usr/local/bin
目錄中,以免與/usr/bin
中的系統工具產生任何衝突。有一個主連結
foo
指向foo-2
或foo-3
。
若要在您的系統上提供替代項,請執行以下步驟:
將您的指令碼複製到
/usr/local/bin
目錄。讓指令碼可執行:
>
sudo
chmod +x /usr/local/bin/foo-{2,3}
針對兩個指令碼執行
update-alternatives
:>
sudo
update-alternatives --install \ /usr/local/bin/foo 1\ foo 2\ /usr/local/bin/foo-2 3\ 200 4>
sudo
update-alternatives --install \ /usr/local/bin/foo 1\ foo 2\ /usr/local/bin/foo-3 3\ 300 4--install
後面的選項具有以下意義:檢查主連結:
>
sudo
update-alternatives --display foo
foo - auto mode link best version is /usr/local/bin/foo-3 link currently points to /usr/local/bin/foo-3 link foo is /usr/local/bin/foo /usr/local/bin/foo-2 - priority 200 /usr/local/bin/foo-3 - priority 300
完成所述步驟後,便可以使用主連結 /usr/local/bin/foo
了。
如果需要,可以安裝其他替代項。若要移除替代項,請使用以下指令:
>
sudo
update-alternatives --remove foo /usr/local/bin/foo-2
移除此指令碼之後,foo 群組的替代項系統看上去如下所示:
>
sudo
update-alternatives --display foo
foo - auto mode link best version is /usr/local/bin/foo-3 link currently points to /usr/local/bin/foo-3 link foo is /usr/local/bin/foo /usr/local/bin/foo-3 - priority 300
22.7 定義相依替代項 #
如果您有替代項,則僅憑指令碼本身不足以完成任務。大部分指令都不是獨立的 — 它們隨附其他檔案,例如延伸、組態或手冊頁。若要建立依賴於主連結的替代項,請使用從屬替代項。
我們假設要延伸第 22.6 節 「安裝自訂替代項」中的範例,並提供手冊頁和組態檔案:
foo-2.1.gz
和foo-3.1.gz
這兩個手冊頁,儲存在/usr/local/man/man1
目錄中。foo-2.conf
和foo-3.conf
這兩個組態檔案,儲存在/etc
中。
請執行以下步驟將其他檔案新增至替代項中:
將組態檔案複製到
/etc
中:>
sudo
cp foo-{2,3}.conf /etc
將手冊頁複製到
/usr/local/man/man1
目錄中:>
sudo
cp foo-{2,3}.1.gz /usr/local/man/man1/
使用
--slave
選項將從屬連結新增至主指令碼:>
sudo
update-alternatives --install \ /usr/local/bin/foo foo /usr/local/bin/foo-2 200 \ --slave /usr/local/man/man1/foo.1.gz \ foo.1.gz \ /usr/local/man/man1/foo-2.1.gz \ --slave /etc/foo.conf \ foo.conf \ /etc/foo-2.conf
>
sudo
update-alternatives --install \ /usr/local/bin/foo foo /usr/local/bin/foo-3 300 \ --slave /usr/local/man/man1/foo.1.gz \ foo.1.gz \ /usr/local/man/man1/foo-3.1.gz \ --slave /etc/foo.conf \ foo.conf \ /etc/foo-3.conf
檢查主連結:
foo - auto mode link best version is /usr/local/bin/foo-3 link currently points to /usr/local/bin/foo-3 link foo is /usr/local/bin/foo slave foo.1.gz is /usr/local/man/man1/foo.1.gz slave foo.conf is /etc/foo.conf /usr/local/bin/foo-2 - priority 200 slave foo.1.gz: /usr/local/man/man1/foo-2.1.gz slave foo.conf: /etc/foo-2.conf /usr/local/bin/foo-3 - priority 300 slave foo.1.gz: /usr/local/man/man1/foo-3.1.gz slave foo.conf: /etc/foo-3.conf
如果您使用 update-alternatives --config foo
將連結變更為 foo-2
,則所有從屬連結也會隨之變更。