您好,登錄后才能下訂單哦!
本篇文章為大家展示了如何分析Linux RPM和YUM包管理,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
先決條件
為了最有效地利用本系列中的文章,您應該具有基本的 Linux 知識,并需要準備一個 Linux 系統用于練習本文介紹的命令。有時候不同版本的程序輸出格式不同,因此您所得到的結果未必總是與這里所示的清單和圖相同,特別是許多輸出高度依賴于系統上已經安裝的包。您自己的輸出可能很不一樣,但是應該能夠看出重要的共同點。
包管理簡介
過去,許多 Linux 程序以源代碼的形式發行,用戶把源代碼構建為所需的程序或程序集;源代碼還附帶必需的手冊頁、配置文件等等。現在,大多數 Linux 發行商使用稱為包 的預構建的程序或程序集,包便于在發行版上安裝。在本文中,學習幫助安裝、更新和刪除包的包管理 工具。本文主要關注 Red Hat 開發的 Red Hat Package Manager (RPM),以及 Duke University 物理系最初為管理 Red Hat Linux 系統開發的 Yellowdog Updater Modified (YUM)。
從用戶的角度來說,基本的包管理功能由命令提供。Linux 開發人員一直致力于讓 Linux 更容易使用,他們開發了其他工具(包括 GUI 工具)來補充基本工具,這對最終用戶隱藏了基本工具的一部分復雜性。在本文和 學習 Linux,101:Debian 包管理 中,我們主要討論基本工具,但是也會提到一些其他工具,讓您能夠繼續研究它們。
RPM、YUM 和 APT(適用于 Debian 系統)有許多相似之處。它們都可以安裝和刪除包。關于安裝的包的信息保存在數據庫中。它們都有基本的命令行功能,同時通過其他工具提供對用戶更友好的界面。它們都可以從 Internet 獲取包。
在安裝 Linux 系統時,通常會安裝許多包。這個集合可能是根據系統的用途定制的,比如服務器、桌面或開發工作站。有時候,可能需要安裝新的包以添加新功能,更新現有的包,甚至刪除不再需要或已經被新的包取代的包。我們來看看如何完成這些任務以及如何解決一些相關的難題,比如尋找包含某一命令的包。
RPM
Red Hat 于 1995 年引入了 RPM。RPM 現在是 Linux Standard Base (LSB) 中采用的包管理系統。rpm 命令選項分為三組:
用于查詢和檢查包
用于安裝、升級和刪除包
用于執行其他功能
在本文中,我們主要關注前兩組命令選項。在 RPM 的手冊頁中可以找到其他功能的相關信息。
還應該注意 rpm 是操作 RPM 的主要命令,而 .rpm 是 RPM 文件使用的擴展名。所以 “一個 rpm” 或 “某某 rpm” 一般是指 RPM 文件,而 rpm 通常指命令。
YUM
YUM 在 RPM 系統中增加了自動更新和包管理,包括依賴關系管理。與 Debian Advanced Packaging Tool (APT) 一樣,除了了解系統上安裝的包之外,YUM 還使用存儲庫。存儲庫是包的集合,通常可以通過網絡連接訪問它們。
安裝 RPM 包
假設您想學 Lisp,一位同事讓您使用 gcl 命令。您試著輸入 gcl --help、which gcl 或 type gcl。但是,如果系統無法找到 gcl,您可能會看到與清單 1 相似的輸出。
清單 1. 沒有找到 gcl 命令
[ian@echidna ~]$ gcl --help bash: gcl: command not found [ian@echidna ~]$ which gcl /usr/bin/which: no gcl in (/usr/lib64/qt-3.3/bin:/usr/kerberos/sbin:/usr/kerber os/bin:/usr/lib64/ccache:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/ sbin:/home/ian/bin) [ian@echidna ~]$ type gcl bash: type: gcl: not found |
您可能會問同事要安裝哪個包,也可能猜想 gcl 命令應該在 gcl 包中。這種猜測常常是對的,但是也不總是。我們稍后會看到如何尋找正確的包。在這里,需要 gcl 包。假設您已經下載或以其他方式獲得了這個包的拷貝,可以使用帶 -i(代表安裝)選項的 rpm 命令安裝它,見清單 2。
清單 2. 用 rpm 安裝 gcl —— 第一次嘗試
[root@echidna ~]# rpm -i gcl-2.6.8-0.6.20090701cvs.fc12.x86_64.rpm error: Failed dependencies: gcl-selinux is needed by gcl-2.6.8-0.6.20090701cvs.fc12.x86_64 |
rpm 命令知道這個包有一個依賴包,但是它并不幫助您解決依賴問題。您需要自己獲取依賴包,然后再次嘗試,看看是否還有其他依賴包 — 重復這個過程,直到滿足所有依賴關系為止。好消息是,可以向 rpm 命令提供要安裝的包的列表,如果滿足所有依賴關系,它會以正確的次序安裝所有包。因此,您至少不必以正確的次序手工安裝每個包。
如果您使用過 Debian 的 APT,可能希望有像 apt-get 命令一樣的功能,apt-get 命令會尋找需要的東西(包括依賴包)并安裝它們。對于基于 RPM 的系統,YUM (Yellowdog Updater Modified) 提供這種功能。清單 3 說明如何使用帶 install 選項的 yum 命令安裝 gcl 和必需的 gcl-selinux 包。
清單 3. 使用 yum 安裝 gcl
[root@echidna ~]# yum install gcl Loaded plugins: presto, refresh-packagekit Setting up Install Process Resolving Dependencies --> Running transaction check ---> Package gcl.x86_64 0:2.6.8-0.7.20100201cvs.fc12 set to be updated --> Processing Dependency: gcl-selinux for package: gcl-2.6.8-0.7.20100201cvs.fc12.x86_64 --> Running transaction check ---> Package gcl-selinux.x86_64 0:2.6.8-0.7.20100201cvs.fc12 set to be updated --> Finished Dependency Resolution Dependencies Resolved ===================================================================================== Package Arch Version Repository Size ===================================================================================== Installing: gcl x86_64 2.6.8-0.7.20100201cvs.fc12 updates 6.3 M Installing for dependencies: gcl-selinux x86_64 2.6.8-0.7.20100201cvs.fc12 updates 17 k Transaction Summary ===================================================================================== Install 2 Package(s) Upgrade 0 Package(s) Total download size: 6.4 M Installed size: 40 M Is this ok [y/N]: y Downloading Packages: Setting up and reading Presto delta metadata updates/prestodelta | 964 kB 00:01 Processing delta metadata Package(s) data still to download: 6.4 M (1/2): gcl-2.6.8-0.7.20100201cvs.fc12.x86_64.rpm | 6.3 MB 00:12 (2/2): gcl-selinux-2.6.8-0.7.20100201cvs.fc12.x86_64.rpm | 17 kB 00:00 ------------------------------------------------------------------------------------- Total 398 kB/s | 6.4 MB 00:16 Running rpm_check_debug Running Transaction Test Transaction Test Succeeded Running Transaction Installing : gcl-selinux-2.6.8-0.7.20100201cvs.fc12.x86_64 1/2 Installing : gcl-2.6.8-0.7.20100201cvs.fc12.x86_64 2/2 Installed: gcl.x86_64 0:2.6.8-0.7.20100201cvs.fc12 Dependency Installed: gcl-selinux.x86_64 0:2.6.8-0.7.20100201cvs.fc12 Complete! |
清單 3 中的輸出表明,YUM 在名為 “updates” 的存儲庫中找到了 gcl.x86_64 0:2.6.8-0.7.20100201cvs.fc12 和 gcl-selinux.x86_64 0:2.6.8-0.7.20100201cvs.fc12(稍后詳細討論),并判斷出總下載大小。按 “y” 同意之后,它下載這兩個包,然后安裝依賴包,最后安裝 gcl。在本文后面會進一步討論依賴關系。
包的位置
在前一節中,學習了如何安裝 RPM 包。但是,包來自什么地方呢?yum 如何知道從哪里下載包?起點是 /etc/yum.repos.d/ 目錄,這個目錄常常包含幾個 repo 文件。這是 repo 的默認位置,但是可以在 YUM 配置文件(通常是 /etc/yum.conf)中指定其他位置。清單 4 給出 fedora-updates.repo,我們從它所對應的位置獲取 gcl 并安裝在我的 Fedora 12 系統上。
典型的 repo 文件分為三個部分,一個用于一般的包,一個用于調試包,最后一個用于源代碼包。常常可以從不同的位置(即鏡像)獲取發行版的包拷貝。所以 repo 文件告訴 yum 在哪里可以找到每個部分的最新鏡像列表。注意,發行版的發布級別和機器架構表示為參數,所以對于我的 x86_64 Fedora 12 系統,yum 會從 https://mirrors.fedoraproject.org/metalink?repo=updates-released-f12&arch=x86_64 下載列表。
除了存儲庫位置之外,repo 文件還指出某個存儲庫是否啟用了,以及是否應該使用 GPG 簽名檢查下載的包。
清單 4. fedora-updates.repo
[ian@echidna ~]$ cat /etc/yum.repos.d/fedora-updates.repo [updates] name=Fedora $releasever - $basearch - Updates failovermethod=priority #baseurl=http://download.fedoraproject.org/pub/fedora/linux/updates/$releasever /$basearch/ mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=updates-released-f$r eleasever&arch=$basearch enabled=1 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-$basearch [updates-debuginfo] name=Fedora $releasever - $basearch - Updates - Debug failovermethod=priority #baseurl=http://download.fedoraproject.org/pub/fedora/linux/updates/$releasever /$basearch/debug/ mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=updates-released-deb ug-f$releasever&arch=$basearch enabled=0 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-$basearch [updates-source] name=Fedora $releasever - Updates Source failovermethod=priority #baseurl=http://download.fedoraproject.org/pub/fedora/linux/updates/$releasever /SRPMS/ mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=updates-released-sou rce-f$releasever&arch=$basearch enabled=0 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-$basearch |
YUM 和 RPM 使用本地數據庫判斷安裝的包。本地數據庫中存儲的包元數據是從啟用的存儲庫獲取的。盡管很少需要為本地數據庫操心,但是可以使用 yum clean 命令清除本地存儲的信息的不同部分,使用 yum makecache 在本地數據庫中為啟用的 repo 創建信息。例如,如果修改了 repo 配置,就可能需要這么做。
刪除 RPM 包
如果要刪除包,可以使用 yum 的 remove 選項或 rpm 的 -e 選項。使用 rpm -e 刪除 gcl 的試運行見清單 5。如果可以刪除這個包,就不會有輸出。
清單 5. 試刪除 gcl
[root@echidna ~]# rpm -e --test gcl |
與使用 apt-get 模擬刪除 Debian 包不同,RPM 系統并不維護自動安裝的包的相關信息,所以無法通過試刪除查明哪些依賴包也可以刪除。但是,如果在單一命令中指定多個要刪除的包,那么沒有依賴關系的包會先于有依賴關系的包刪除。
與安裝包不同,當使用 rpm 刪除包時,在刪除包之前沒有提示。但是,如果試圖刪除其他包需要的包,它不會執行刪除操作,您會看到清單 6 所示的錯誤消息。
清單 6. 用 rpm 刪除依賴包
[root@echidna ~]# rpm -e gcl-selinux error: Failed dependencies: gcl-selinux is needed by (installed) gcl-2.6.8-0.7.20100201cvs.fc12.x86_64 |
如果使用 yum remove,在執行事務測試之后會顯示提示。如果試圖刪除的包是其他已安裝包的依賴包,YUM 會提議刪除這些包和依賴包,見清單 7。
清單 7. 用 yum 刪除依賴包
[root@echidna ~]# yum remove gcl-selinux Loaded plugins: presto, refresh-packagekit Setting up Remove Process Resolving Dependencies --> Running transaction check ---> Package gcl-selinux.x86_64 0:2.6.8-0.7.20100201cvs.fc12 set to be erased --> Processing Dependency: gcl-selinux for package: gcl-2.6.8-0.7.20100201cvs.fc12.x86_64 --> Running transaction check ---> Package gcl.x86_64 0:2.6.8-0.7.20100201cvs.fc12 set to be erased --> Finished Dependency Resolution Dependencies Resolved ===================================================================================== Package Arch Version Repository Size ===================================================================================== Removing: gcl-selinux x86_64 2.6.8-0.7.20100201cvs.fc12 @updates 90 k Removing for dependencies: gcl x86_64 2.6.8-0.7.20100201cvs.fc12 @updates 40 M Transaction Summary ===================================================================================== Remove 2 Package(s) Reinstall 0 Package(s) Downgrade 0 Package(s) Is this ok [y/N]: n Exiting on user Command Complete! |
升級 RPM 包
既然已經了解了如何安裝和刪除 RPM,我們來看看如何把 RPM 包升級到更高級別。可以使用 yum update 更新整個系統,還可以指定單一包或通配符。清單 8 說明如何更新所有名稱以 “gr” 開頭的包。注意,這里使用撇號防止 shell 展開 “*”。
清單 8. 使用 yum update 執行更新
[root@echidna ~]# yum update 'gr*' Loaded plugins: presto, refresh-packagekit Setting up Update Process Resolving Dependencies --> Running transaction check ---> Package grep.x86_64 0:2.6.3-1.fc12 set to be updated ---> Package groff.x86_64 0:1.18.1.4-20.fc12 set to be updated --> Finished Dependency Resolution Dependencies Resolved ===================================================================================== Package Arch Version Repository Size ===================================================================================== Updating: grep x86_64 2.6.3-1.fc12 updates 228 k groff x86_64 1.18.1.4-20.fc12 updates 1.5 M Transaction Summary ===================================================================================== Install 0 Package(s) Upgrade 2 Package(s) Total download size: 1.7 M Is this ok [y/N]: y Downloading Packages: Setting up and reading Presto delta metadata Processing delta metadata Download delta size: 854 k http://fedora.fastsoft.net/pub/linux/fedora/linux/updates/12/x86_64/drpms/grep-2.5.3- 6.fc12_2.6.3-1.fc12.x86_64.drpm: [Errno 14] HTTP Error 404 : http://fedora.fastsoft.n et/pub/linux/fedora/linux/updates/12/x86_64/drpms/grep-2.5.3-6.fc12_2.6.3-1.fc12.x86_ 64.drpm Trying other mirror. (1/2): grep-2.5.3-6.fc12_2.6.3-1.fc12.x86_64.drpm | 214 kB 00:00 (2/2): groff-1.18.1.4-18.fc12_1.18.1.4-20.fc12.x86_64.drpm | 640 kB 00:00 Finishing rebuild of rpms, from deltarpms <delta rebuild> | 1.7 MB 00:02 Presto reduced the update size by 52% (from 1.7 M to 854 k). Running rpm_check_debug Running Transaction Test Transaction Test Succeeded Running Transaction Updating : grep-2.6.3-1.fc12.x86_64 1/4 Updating : groff-1.18.1.4-20.fc12.x86_64 2/4 Cleanup : grep-2.5.3-6.fc12.x86_64 3/4 Cleanup : groff-1.18.1.4-18.fc12.x86_64 4/4 Updated: grep.x86_64 0:2.6.3-1.fc12 groff.x86_64 0:1.18.1.4-20.fc12 Complete! |
如果知道 RPM 文件的位置,或者已經下載了它們,那么也可以使用 rpm 命令執行更新。這與安裝相似,只是要使用 -U 或 -F 選項而不是 -i 選項。這兩個選項的差異是, -U 選項更新現有的包,如果這個包還沒有安裝,就安裝它;而 -F 選項只升級或刷新 已經安裝的包。因此,經常使用 -U 選項,尤其是在命令行包含 RPM 列表的情況下。這樣的話,就會安裝未安裝的包,升級已經安裝的包。常常使用另外兩個選項 -v(詳細)和 -h(# 標志)提供進度顯示。清單 9 說明如何使用 rpm 命令更新 vim-common、vim-enhanced 和 vim-minimal 包。我們已經把 vim-common 和 vim-enhanced 包下載到根用戶的主目錄中,而 vim-minimal 包要從一個更新鏡像獲取。
清單 9. 用 rpm 更新包
[root@echidna ~]# ls *.rpm vim-common-7.2.411-1.fc12.x86_64.rpm vim-enhanced-7.2.411-1.fc12.x86_64.rpm [root@echidna ~]# rpm -Uvh *.rpm http://mirrors.usc.edu/pub/linux/distributions\ > /fedora/linux/updates/12/x86_64/vim-minimal-7.2.411-1.fc12.x86_64.rpm Retrieving http://mirrors.usc.edu/pub/linux/distributions/fedora/linux/updates/12/x86 _64/vim-minimal-7.2.411-1.fc12.x86_64.rpm Preparing... ########################################### [100%] 1:vim-common ########################################### [ 33%] 2:vim-enhanced ########################################### [ 67%] 3:vim-minimal ########################################### [100%] |
查詢 RPM 包
您在前面的示例中看到,用 rpm 命令安裝 rpm 需要包文件的完整名稱(或 URL),比如 gcl-2.6.8-0.6.20090701cvs.fc12.x86_64.rpm。另一方面,用 yum 安裝或用這兩個命令刪除 rpm 只需要包名,比如 gcl。與 APT 一樣,RPM 在內部數據庫中維護安裝的包的信息,因此允許使用包名操作安裝的包。在本節中,看看可以使用 rpm 的 -q(代表查詢)選項或相關聯的 yum 查詢從數據庫獲取的一些信息。
基本查詢只檢查包是否已經安裝了,如果安裝了,就查詢版本。增加 -i 選項會得到包的相關信息。注意,安裝、升級或刪除包需要根權力,但是非根用戶也可以查詢 rpm 數據庫。
清單 10. 顯示 gcl 的相關信息
[ian@echidna ~]$ yum list gcl Loaded plugins: presto, refresh-packagekit Installed Packages gcl.x86_64 2.6.8-0.7.20100201cvs.fc12 @updates [ian@echidna ~]$ rpm -q gcl gcl-2.6.8-0.7.20100201cvs.fc12.x86_64 [ian@echidna ~]$ yum info gcl Loaded plugins: presto, refresh-packagekit Installed Packages Name : gcl Arch : x86_64 Version : 2.6.8 Release : 0.7.20100201cvs.fc12 Size : 40 M Repo : installed From repo : updates Summary : GNU Common Lisp URL : http://www.gnu.org/software/gcl/ License : GPL+ and LGPLv2+ Description: GCL is a Common Lisp currently compliant with the ANSI standard. : Lisp compilation produces native code through the intermediary of : the system's C compiler, from which GCL derives efficient : performance and facile portability. Currently uses TCL/Tk as GUI. [ian@echidna ~]$ rpm -qi gcl Name : gcl Relocations: (not relocatable) Version : 2.6.8 Vendor: Fedora Project Release : 0.7.20100201cvs.fc12 Build Date: Tue 23 Mar 2010 03:20:36 PM EDT Install Date: Wed 05 May 2010 01:01:34 PM EDT Build Host: x86-02.phx2.fedoraproject. org Group : Development/Languages Source RPM: gcl-2.6.8-0.7.20100201cvs.fc12.sr c.rpm Size : 41667750 License: GPL+ and LGPLv2+ Signature : RSA/8, Tue 23 Mar 2010 04:14:06 PM EDT, Key ID 9d1cc34857bbccba Packager : Fedora Project URL : http://www.gnu.org/software/gcl/ Summary : GNU Common Lisp Description : GCL is a Common Lisp currently compliant with the ANSI standard. Lisp compilation produces native code through the intermediary of the system's C compiler, from which GCL derives efficient performance and facile portability. Currently uses TCL/Tk as GUI. |
詳細的清單顯示與 RPM 包相關聯的一些標記。注意,rpm 和 yum 以不同的格式顯示不同的信息。在本文中,我們都使用標準命令選項提供的基本輸出。如果希望使用 rpm --queryformat 選項定制查詢輸出,請參考手冊頁。如果希望了解您的 rpm 版本支持的所有標記,應該運行 rpm --querytags。
如清單 10 所示,可以使用 yum 列出安裝的包。還可以用它列出有更新可用的包、可以安裝的包以及具有其他性質的包,比如廢棄的包或存儲庫中最近添加的包。甚至可以使用 yum 搜索包。在清單 11 中可以看到,texmacs 包還沒有安裝,但是可以從 fedora 存儲庫獲取它。如果搜索 “texmacs”,會看到提到它的四個包。很容易看出為什么會找到 TeXmacs* 包。使用 yum info pydot 查明為什么也會找到 pydot 包。
清單 11. 搜索 "texmacs"
[ian@echidna ~]$ yum list texmacs Loaded plugins: presto, refresh-packagekit Available Packages TeXmacs.x86_64 1.0.7.2-2.fc12 fedora [ian@echidna ~]$ yum search texmacs Loaded plugins: presto, refresh-packagekit ================================= Matched: texmacs ================================== TeXmacs-devel.i686 : Development files for TeXmacs TeXmacs-devel.x86_64 : Development files for TeXmacs TeXmacs.x86_64 : Structured wysiwyg scientific text editor pydot.noarch : Python interface to Graphviz's Dot language |
對于后面的查詢示例,我們主要使用 rpm,因為它的選項更豐富。許多示例也可以使用 yum 完成,yum 有一些基本 rpm 選項不具備的功能。
RPM 包和其中的文件
用戶常常希望知道一個包中有哪些文件,或者某個文件來自哪個包。使用 -ql 選項列出 gcl 包中的文件,見清單 12。這個包中有許多文件,所以這里只給出部分輸出。
清單 12. 顯示 gcl 包中的文件
[ian@echidna ~]$ rpm -ql gcl /usr/bin/gcl /usr/lib/gcl-2.6.8 /usr/lib/gcl-2.6.8/clcs /usr/lib/gcl-2.6.8/clcs/sys-proclaim.lisp /usr/lib/gcl-2.6.8/cmpnew /usr/lib/gcl-2.6.8/cmpnew/gcl_cmpmain.lsp /usr/lib/gcl-2.6.8/cmpnew/gcl_cmpopt.lsp /usr/lib/gcl-2.6.8/cmpnew/gcl_collectfn.lsp . . . /usr/share/info/gcl-tk.info.gz /usr/share/info/gcl.info-1.gz /usr/share/info/gcl.info-2.gz /usr/share/info/gcl.info-3.gz /usr/share/info/gcl.info-4.gz /usr/share/info/gcl.info-5.gz /usr/share/info/gcl.info-6.gz /usr/share/info/gcl.info-7.gz /usr/share/info/gcl.info-8.gz /usr/share/info/gcl.info-9.gz /usr/share/info/gcl.info.gz /usr/share/man/man1/gcl.1.gz |
通過在查詢中添加 -c 選項,可以把列出的文件限制為配置文件。-d 選項把輸出限制為文檔文件。
查詢包文件
上面的包查詢命令在 RPM 數據庫中查詢已經安裝的包。如果剛下載了一個包,想獲取同類信息,可以在查詢中使用 -p(代表包文件)選項并指定包的文件 名(與安裝包時一樣)。清單 13 顯示前面下載的兩個 vim 包的信息。我們只作為根用戶運行它,因為文件在根用戶的主目錄中。可以添加其他查詢選項,比如用 -l 列出文件,用 -i 列出信息。
清單 13. 顯示兩個 vim 包的包文件信息
[root@echidna ~]# rpm -qp *.rpm vim-common-7.2.411-1.fc12.x86_64 vim-enhanced-7.2.411-1.fc12.x86_64 |
查詢安裝的所有包
-a 選項把查詢應用于安裝的所有包。這會生成許多輸出,所以通常同時使用一個或多個篩選器,比如用 sort 進行排序,用 more 或 less 進行分頁輸出,用 wc 獲取包或文件內容,用 grep 搜索您不確定名稱的包。清單 14 給出以下查詢:
系統上所有包的排序列表
系統上所有包的數量
系統上所有包中的所有文件的數量
用 RPM 安裝的所有文檔文件的數量
搜索名稱中包含 “gcl” 的所有包(區分大小寫)
清單 14. 對所有包執行查詢
[ian@echidna ~]$ rpm -qa | sort | more aalib-libs-1.4.0-0.18.rc5.fc12.x86_64 abrt-1.0.8-2.fc12.x86_64 abrt-addon-ccpp-1.0.8-2.fc12.x86_64 abrt-addon-kerneloops-1.0.8-2.fc12.x86_64 abrt-addon-python-1.0.8-2.fc12.x86_64 abrt-desktop-1.0.8-2.fc12.x86_64 abrt-gui-1.0.8-2.fc12.x86_64 abrt-libs-1.0.8-2.fc12.x86_64 abrt-plugin-bugzilla-1.0.8-2.fc12.x86_64 abrt-plugin-logger-1.0.8-2.fc12.x86_64 abrt-plugin-runapp-1.0.8-2.fc12.x86_64 abyssinica-fonts-1.0-5.fc12.noarch acl-2.2.49-2.fc12.x86_64 ... [ian@echidna ~]$ rpm -qa | wc -l 1792 [ian@echidna ~]$ rpm -qal | wc -l 281052 [ian@echidna ~]$ rpm -qad | wc -l 45686 [ian@echidna ~]$ rpm -qa | grep -i gcl gcl-selinux-2.6.8-0.7.20100201cvs.fc12.x86_64 gcl-2.6.8-0.7.20100201cvs.fc12.x86_64 |
使用 rpm -qa 可以簡化對多個系統的管理。如果把排序的輸出重定向到一臺機器上的文件,然后在另一臺機器上也這么做,就可以使用 diff 程序尋找差異。
哪個包包含某一文件?
既然可以列出所有包和一個包中的所有文件,現在就掌握了查明哪個包包含某一文件所需的所有信息。但是,rpm 命令的 -f(或 --file)選項可以幫助找到包含某一文件的包。假設您想知道前面看到的哪個 vim 包提供 vim 命令。您需要文件的完整路徑。清單 15 說明如何使用 which 命令得到 vim 命令的完整路徑,可以使用這個輸出作為 rpm -qf 命令的輸入。注意,`which guile-config` 前后的符號是反撇號。在 Bash shell 中,另一種使用方法是 $(which vim)。
清單 15. 哪個包提供 vim 可執行文件
[ian@echidna ~]$ which vim /usr/bin/vim [ian@echidna ~]$ rpm -qf `which vim` vim-enhanced-7.2.411-1.fc12.x86_64 [ian@echidna ~]$ rpm -qf $(which vim) vim-enhanced-7.2.411-1.fc12.x86_64 |
RPM 依賴關系
在前面看到刪除 gcl-selinux 包的操作失敗了,這是因為存在依賴關系。除了文件之外,RPM 包可能包含其他包所依賴的任意功能。
如您所見,依賴關系通常會正常發揮作用。如果需要同時安裝幾個包,其中一些依賴于其他包,那么只需使用 yum,或者向 rpm -Uvh 命令提供完整的列表,它會分析依賴關系并按正確的次序執行安裝。
除了在安裝或刪除包時產生的錯誤消息之外,還可以通過幾種方法查明包需要或依賴的文件或功能。
rpm 命令提供的一個選項可以查詢安裝的包或包文件,從而查明它們依賴或需要 什么功能。這個選項是 --requires,它可以簡寫為 -R。清單 16 顯示 gcl 需要的功能。如果要查詢包文件而不是 RPM 數據庫,那么添加 -p 選項并使用完整的 RPM 文件名。
清單 16. gcl 需要什么
[ian@echidna ~]$ rpm -qR gcl /bin/sh /bin/sh /bin/sh /sbin/install-info /sbin/install-info gcl-selinux libX11.so.6()(64bit) libc.so.6()(64bit) libc.so.6(GLIBC_2.11)(64bit) libc.so.6(GLIBC_2.2.5)(64bit) libc.so.6(GLIBC_2.3)(64bit) libc.so.6(GLIBC_2.3.4)(64bit) libc.so.6(GLIBC_2.4)(64bit) libc.so.6(GLIBC_2.7)(64bit) libc.so.6(GLIBC_2.8)(64bit) libdl.so.2()(64bit) libgmp.so.3()(64bit) libm.so.6()(64bit) libm.so.6(GLIBC_2.2.5)(64bit) libreadline.so.6()(64bit) libtcl8.5.so()(64bit) libtk8.5.so()(64bit) libz.so.1()(64bit) rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1 rtld(GNU_HASH) rpmlib(PayloadIsXz) <= 5.2-1 |
把功能與提供它們的包聯系起來不太容易。帶 deplist 選項的 yum 命令可以提供幫助。如果只指定包名,沒有版本號,可能會得到其他已知版本的列表。清單 17 說明如何獲得安裝的 gcl 版本的依賴列表。
清單 17. 使用 yum deplist 查明 gcl 需要什么
[ian@echidna ~]$ yum deplist $(rpm -q gcl) Loaded plugins: presto, refresh-packagekit Finding dependencies: package: gcl.x86_64 2.6.8-0.7.20100201cvs.fc12 dependency: libc.so.6(GLIBC_2.3.4)(64bit) provider: glibc.x86_64 2.11-2 provider: glibc.x86_64 2.11.1-6 dependency: gcl-selinux provider: gcl-selinux.x86_64 2.6.8-0.6.20090701cvs.fc12 provider: gcl-selinux.x86_64 2.6.8-0.7.20100201cvs.fc12 dependency: libgmp.so.3()(64bit) provider: gmp.x86_64 4.3.1-5.fc12 dependency: libc.so.6(GLIBC_2.8)(64bit) provider: glibc.x86_64 2.11-2 provider: glibc.x86_64 2.11.1-6 dependency: libc.so.6(GLIBC_2.4)(64bit) provider: glibc.x86_64 2.11-2 provider: glibc.x86_64 2.11.1-6 dependency: libc.so.6()(64bit) provider: glibc.x86_64 2.11-2 provider: glibc.x86_64 2.11.1-6 dependency: /sbin/install-info provider: info.x86_64 4.13a-7.fc12 provider: info.x86_64 4.13a-9.fc12 dependency: libX11.so.6()(64bit) provider: libX11.x86_64 1.3-1.fc12 dependency: libc.so.6(GLIBC_2.7)(64bit) provider: glibc.x86_64 2.11-2 provider: glibc.x86_64 2.11.1-6 dependency: libtcl8.5.so()(64bit) provider: tcl.x86_64 1:8.5.7-4.fc12 provider: tcl.x86_64 1:8.5.7-5.fc12 dependency: libc.so.6(GLIBC_2.11)(64bit) provider: glibc.x86_64 2.11-2 provider: glibc.x86_64 2.11.1-6 dependency: libtk8.5.so()(64bit) provider: tk.x86_64 1:8.5.7-2.fc12 provider: tk.x86_64 1:8.5.7-3.fc12 dependency: libc.so.6(GLIBC_2.3)(64bit) provider: glibc.x86_64 2.11-2 provider: glibc.x86_64 2.11.1-6 dependency: libm.so.6()(64bit) provider: glibc.x86_64 2.11-2 provider: glibc.x86_64 2.11.1-6 dependency: libz.so.1()(64bit) provider: zlib.x86_64 1.2.3-23.fc12 dependency: rtld(GNU_HASH) provider: glibc.i686 2.11-2 provider: glibc.x86_64 2.11-2 provider: glibc.x86_64 2.11.1-6 provider: glibc.i686 2.11.1-6 dependency: libdl.so.2()(64bit) provider: glibc.x86_64 2.11-2 provider: glibc.x86_64 2.11.1-6 dependency: libreadline.so.6()(64bit) provider: readline.x86_64 6.0-3.fc12 dependency: /bin/sh provider: bash.x86_64 4.0.33-1.fc12 provider: bash.x86_64 4.0.35-3.fc12 dependency: libc.so.6(GLIBC_2.2.5)(64bit) provider: glibc.x86_64 2.11-2 provider: glibc.x86_64 2.11.1-6 dependency: libm.so.6(GLIBC_2.2.5)(64bit) provider: glibc.x86_64 2.11-2 provider: glibc.x86_64 2.11.1-6 |
這個列表還顯示每個功能可能的提供者。可以看到大多數依賴功能可以由多個包級別提供。例如,/bin/sh 可以來自 bash 的兩個級別之一。通過使用創造性的篩選,可以把輸出縮減為清單 18 所示的包名列表。
清單 18. 把 yum deplist 的輸出縮減為只列出包名
[ian@echidna ~]$ yum deplist $(rpm -q gcl) | grep "provider:" | \ > awk '{ print $2 }'|sort|uniq bash.x86_64 gcl-selinux.x86_64 glibc.i686 glibc.x86_64 gmp.x86_64 info.x86_64 libX11.x86_64 readline.x86_64 tcl.x86_64 tk.x86_64 zlib.x86_64 |
如果只想知道需要安裝哪些包,可以運行 yum install,查看在提示接受安裝提議之前顯示的列表。
除了查明包需要的功能之外,還可能需要了解哪個包提供某一功能。前面演示了如何查明哪個包包含某一文件。清單 19 說明如何使用 rpm 或 yum 查明哪個包提供 gcl-selinux(x86-64) 功能。除了顯示提供此功能的已安裝包的信息之外,YUM 還顯示存儲庫中可用的包或版本。可以看到,原來的 2.6.8-0.6 版來自 fedora 存儲庫,而 updates 存儲庫中有更新的 2.6.8-0.7 版。
清單 19. 哪個包提供 gcl-selinux(x86-64) 功能
[ian@echidna ~]$ rpm -q --whatprovides 'gcl-selinux(x86-64)' gcl-selinux-2.6.8-0.7.20100201cvs.fc12.x86_64 [ian@echidna ~]$ yum whatprovides 'gcl-selinux(x86-64)' Loaded plugins: presto, refresh-packagekit gcl-selinux-2.6.8-0.6.20090701cvs.fc12.x86_64 : SELinux policy for GCL images Repo : fedora Matched from: Other : gcl-selinux(x86-64) gcl-selinux-2.6.8-0.7.20100201cvs.fc12.x86_64 : SELinux policy for GCL images Repo : updates Matched from: Other : gcl-selinux(x86-64) gcl-selinux-2.6.8-0.7.20100201cvs.fc12.x86_64 : SELinux policy for GCL images Repo : installed Matched from: Other : Provides-match: gcl-selinux(x86-64) |
RPM 包文件完整性
為了確保完整性,RPM 包包含一個摘要(比如 MD5 或 SHA1),常常經過數字簽名。數字簽名的包需要用公共密鑰進行檢驗。使用 rpm 的 --checksig(簡寫為 -K)選項檢查 RPM 包文件的完整性。添加 -v 選項以生成更詳細的輸出常常有幫助。清單 20 給出的示例檢查 vim-enhanced RPM 的完整性。
清單 20. 檢查 vim-enhanced 包文件的完整性
[root@echidna ~]# rpm -vK vim-enhanced-7.2.411-1.fc12.x86_64.rpm vim-enhanced-7.2.411-1.fc12.x86_64.rpm: Header V3 RSA/SHA256 signature: OK, key ID 57bbccba Header SHA1 digest: OK (f9a199545a515f7ff0716729768b41eb68fe29a8) V3 RSA/SHA256 signature: OK, key ID 57bbccba MD5 digest: OK (d4045f1f72d48073e3f401ee9d1f71cf) |
可能會產生下面的輸出:
V3 DSA signature: NOKEY, key ID 16a61572
這意味著這個包是經過簽名的,但是您的 RPM 數據庫中沒有所需的公共密鑰。注意,以前版本的 RPM 可能以不同的方式提供檢驗。
如果包是經過簽名的,您希望根據簽名檢驗它,就需要找到適當的簽名文件并把它導入 RPM 數據庫。應該首先下載密鑰,然后檢查它的指紋,最后使用 rpm --import 命令導入它。更多信息參見 RPM 手冊頁。還可以在 RPM 主頁上找到關于簽名的二進制代碼的更多信息(見 參考資料 中的鏈接)。
檢驗安裝的包
與檢查 rpm 的完整性一樣,還可以使用 rpm -V 檢查已安裝的文件的完整性。這個步驟確保從 rpm 安裝文件之后文件沒有修改過。如清單 21 所示,如果包仍然良好,這個命令沒有輸出;但是,可以添加 -v 選項以產生更詳細的輸出。
清單 21. 檢驗已安裝的 vim-common 包
[ian@echidna ~]$ rpm -V vim-common |
現在,我們作為根用戶刪除 /usr/bin/xxd 并把 /usr/share/vim/vim72/syntax/bindzone.vim 替換為 /bin/bash。然后再次檢查。結果見清單 22。
清單 22. 篡改 vim-common 包
[root@echidna ~]# rpm -qf /usr/bin/xxd /usr/share/vim/vim72/syntax/bindzone.vim vim-common-7.2.411-1.fc12.x86_64 vim-common-7.2.411-1.fc12.x86_64 [root@echidna ~]# rm /usr/bin/xxd rm: remove regular file `/usr/bin/xxd'? y [root@echidna ~]# cp /bin/bash /usr/share/vim/vim72/syntax/bindzone.vim cp: overwrite `/usr/share/vim/vim72/syntax/bindzone.vim'? y [root@echidna ~]# rpm -V vim-common missing /usr/bin/xxd S.5....T. /usr/share/vim/vim72/syntax/bindzone.vim |
輸出表明對 /usr/share/vim/vim72/syntax/bindzone.vim 文件的 MD5 和、文件大小和 mtime 檢查失敗了。解決這個問題的一種方法是刪除這個包,然后重新安裝,依賴于 vim-common 的其他已安裝包仍然可以正常運行。這個解決方案使用 rpm 的 --force 選項或 yum 的 reinstall 功能強制重新安裝。清單 23 演示如何用 yum 重新安裝,然后檢查包現在是否良好,檢查刪除的文件是否已經恢復了。
清單 23. 重新安裝 vim-common 包
[root@echidna ~]# yum reinstall vim-common Loaded plugins: presto, refresh-packagekit Setting up Reinstall Process Resolving Dependencies --> Running transaction check ---> Package vim-common.x86_64 2:7.2.411-1.fc12 set to be updated --> Finished Dependency Resolution Dependencies Resolved ===================================================================================== Package Arch Version Repository Size ===================================================================================== Reinstalling: vim-common x86_64 2:7.2.411-1.fc12 updates 6.0 M Transaction Summary ===================================================================================== Remove 0 Package(s) Reinstall 1 Package(s) Downgrade 0 Package(s) Total download size: 6.0 M Installed size: 17 M Is this ok [y/N]: y Downloading Packages: Setting up and reading Presto delta metadata updates/prestodelta | 969 kB 00:00 Processing delta metadata Package(s) data still to download: 6.0 M vim-common-7.2.411-1.fc12.x86_64.rpm | 6.0 MB 00:01 Running rpm_check_debug Running Transaction Test Transaction Test Succeeded Running Transaction Warning: RPMDB altered outside of yum. Installing : 2:vim-common-7.2.411-1.fc12.x86_64 1/1 Installed: vim-common.x86_64 2:7.2.411-1.fc12 Complete! [root@echidna ~]# rpm -V vim-common [root@echidna ~]# ls /usr/bin/xxd /usr/bin/xxd |
如果需要更有力的措施
包管理系統通常可以恢復包。但是,如果刪除了包中的重要文件,重新安裝包但不刪除無法解決問題,那么可能需要在重新安裝之前刪除包。對于這種情況,可能希望刪除現有的拷貝并重新安裝,但是不希望卸載和重新安裝依賴它的所有包。為此,在刪除包時,可以使用 rpm 命令的 --nodeps 選項繞過依賴關系檢查。在清單 24 中,刪除了 vim-common 中的 /usr/bin/xxd 文件,然后演示如何恢復這個包。
清單 24. 用 rpm 更新包
[root@echidna ~]# rm /usr/bin/xxd rm: remove regular file `/usr/bin/xxd'? y [root@echidna ~]# # Oops! we needed that file [root@echidna ~]# rpm -Fvh vim-common-7.2.411-1.fc12.x86_64.rpm [root@echidna ~]# ls /usr/bin/xxd ls: cannot access /usr/bin/xxd: No such file or directory [root@echidna ~]# # Oh! Freshening the package didn't replace the missing file [root@echidna ~]# rpm -e vim-common error: Failed dependencies: vim-common = 2:7.2.411-1.fc12 is needed by (installed) vim-enhanced-2:7.2.411-1.f c12.x86_64 [root@echidna ~]# # Can't remove vim-common because vim-enhanced needs it [root@echidna ~]# rpm -e --nodeps vim-common [root@echidna ~]# # Bypassing the dependency check allowed removal [root@echidna ~]# rpm -Uvh vim-common-7.2.411-1.fc12.x86_64.rpm Preparing... ########################################### [100%] 1:vim-common ########################################### [100%] [root@echidna ~]# # Update (or install) vim-common again [root@echidna ~]# ls /usr/bin/xxd /usr/bin/xxd [root@echidna ~]# # And /usr/bin/xxd is back |
現在,如果發生意外或一般的更新失敗,您可以以幾種方法更新或修復。注意,在安裝 RPM 時也可以繞過依賴關系檢查,但是這通常不是好做法。
從存儲庫下載 RPM
盡管 yum 會自動地從存儲庫獲取包,但是您可能希望下載并保存 RPM,比如為了在不連網的系統上安裝它們、為了檢查它們的內容或有其他原因。可以使用清單 25 所示的 yumdownloader 命令。對于我們的示例,這個包已經安裝了,所以沒有要下載的包。如果有這樣的包,可以使用 --resolve 選項再次下載它們。
清單 25. 下載 gcl 包
[ian@echidna ~]$ yumdownloader --resolve gcl Loaded plugins: presto, refresh-packagekit adobe-linux-i386 17/17 --> Running transaction check ---> Package gcl.x86_64 0:2.6.8-0.7.20100201cvs.fc12 set to be updated --> Finished Dependency Resolution gcl-2.6.8-0.7.20100201cvs.fc12.x86_64.rpm | 6.3 MB 00:01 |
使用 rpm2cpio
如果下載一個 RPM,需要檢查它的內容而不是安裝它,可以使用 rpm2cpio 命令把內容轉換為 cpio 存檔,然后通過 cpio 命令提取出包中的某些或所有文件。清單 26 對 gcl-selinux 包執行轉換,然后顯示提取出的文件(和目錄)。關于 rpm2cpio 和 cpio 命令的更多信息參見它們的手冊頁。
清單 26. 用 rpm2cpio 提取 gcl-selinux 包
[ian@echidna ~]$ yumdownloader gcl-selinux Loaded plugins: presto, refresh-packagekit gcl-selinux-2.6.8-0.7.20100201cvs.fc12.x86_64.rpm | 17 kB 00:00 [ian@echidna ~]$ mkdir gcl-selinux [ian@echidna ~]$ cd gcl-selinux [ian@echidna gcl-selinux]$ rpm2cpio ../gcl-selinux*.rpm | cpio -idv ./usr/share/selinux/packages/gcl ./usr/share/selinux/packages/gcl/gcl.pp 182 blocks [ian@echidna gcl-selinux]$ find . . ./usr ./usr/share ./usr/share/selinux ./usr/share/selinux/packages ./usr/share/selinux/packages/gcl ./usr/share/selinux/packages/gcl/gcl.pp |
尋找 RPM
我們在前面看到 YUM 提供了搜索功能,可以搜索包描述和包名。如果需要查明哪個包包含某個還沒有安裝的程序,還有幾種方法:
可以猜測可能包含它的包,下載這個包,但是不安裝。得到這個包之后,就可以查詢它。
可以搜索 Internet。
可以試試下面介紹的 command-not-found 功能。
如果通過系統工具無法找到某個 RPM,可以通過 Rpmfind.Net 服務器尋找 RPM。
命令未找到
如果 Bash shell 搜索一個命令,但是沒有找到,那么 shell 就搜索 shell 函數 command_not_found_handle。如果 command_not_found_handle 函數存在,shell 以原來的命令和參數作為參數調用它,函數的退出狀態成為 shell 的退出狀態。如果沒有定義此函數,shell 輸出錯誤消息并返回退出狀態 127。常常在系統 /etc/bash.bashrc 文件中設置此函數。清單 27 說明如何搜索 command-not-found 功能并安裝它。
清單 27. 尋找并安裝 command-not-found 功能
[root@echidna ~]# yum search command-not-found Loaded plugins: presto, refresh-packagekit ========================== Matched: command-not-found ========================== PackageKit-command-not-found.x86_64 : Ask the user to install command line : programs automatically You have new mail in /var/spool/mail/root [root@echidna ~]# yum install PackageKit-command-not-found.x86_64 Loaded plugins: presto, refresh-packagekit Setting up Install Process Resolving Dependencies --> Running transaction check ---> Package PackageKit-command-not-found.x86_64 0:0.5.7-2.fc12 set to be updated --> Finished Dependency Resolution Dependencies Resolved ================================================================================ Package Arch Version Repository Size ================================================================================ Installing: PackageKit-command-not-found x86_64 0.5.7-2.fc12 updates 102 k Transaction Summary ================================================================================ Install 1 Package(s) Upgrade 0 Package(s) Total download size: 102 k Installed size: 262 k Is this ok [y/N]: y Downloading Packages: Setting up and reading Presto delta metadata Processing delta metadata Package(s) data still to download: 102 k PackageKit-command-not-found-0.5.7-2.fc12.x86_64.rpm | 102 kB 00:00 Running rpm_check_debug Running Transaction Test Transaction Test Succeeded Running Transaction Installing : PackageKit-command-not-found-0.5.7-2.fc12.x86_64 1/1 Installed: PackageKit-command-not-found.x86_64 0:0.5.7-2.fc12 Complete! |
清單 28 說明在安裝 PackageKit-command-not-found 之后如何定義這個函數。如果函數無法執行搜索,那么它模擬標準的系統行為,返回 127。
清單 28. command_not_found_handle
[ian@echidna ~]$ type command_not_found_handle command_not_found_handle is a function command_not_found_handle () { runcnf=1; retval=127; [ ! -S /var/run/dbus/system_bus_socket ] && runcnf=0; [ ! -x /usr/sbin/packagekitd ] && runcnf=0; if [ $runcnf -eq 1 ]; then /usr/libexec/pk-command-not-found $1; retval=$?; else echo "bash: $1: command not found"; fi; return $retval } |
如果在 清單 1 中運行 gcl 之前安裝了這個功能,可能會看到清單 29 所示的輸出。
清單 29. 安裝 command_not_found_handle 之后嘗試運行 gcl
[ian@echidna ~]$ gcl Command not found. Install package 'gcl' to provide command 'gcl'? [N/y] |
其他工具
除了 yum 和 rpm 之外,發行商可能提供了用于從存儲庫安裝包或更新整個系統的其他工具。這些工具可能是圖形化工具或命令行工具,或者同時提供這兩種界面。例如:
YaST (SUSE)
up2date (Red Hat)
Mandrake Software Management (Mandriva)
通常,這些工具以自動或半自動方式處理多個包更新。它們還可能提供顯示存儲庫內容或搜索包的功能。更多信息參見發行版的文檔。
PackageKit
討論包安裝就不能不提到 PackageKit,這是一個為更方便地安裝和更新軟件而設計的系統。它的意圖是把不同發行版中使用的所有軟件圖形化工具統一起來。PackageKit 使用一個由系統激活的守護進程,這意味著這個守護進程只在需要時激活。Packagekit 有適用于 Gnome (gnome-packagekit) 和 KDE (KPackageKit) 的版本。上面介紹的 command-not-found 功能也是 PackageKit 的組成部分。它包括命令 pkcon(從控制臺執行包管理功能)和 pkmon(監視包集活動)。它還包含用于添加軟件包或更新系統的圖形化工具。圖 1 給出 Software Update 圖形界面的示例。
圖 1. Fedora 12 (Gnome) 上的 Software Update 圖形界面
除了這里討論的內容,RPM 和 YUM 包管理系統還有許多特性。本文介紹就到這里為止,想要更加深入的了解,可以參考其他的文章和資料。
上述內容就是如何分析Linux RPM和YUM包管理,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。