学习 Linux,101: RPM 和 YUM 包管理

添加新软件并及时更新系统

学习如何在 Linux® 系统上安装、升级和管理包。本文主要关注由 Red Hat 开发的 Red Hat Package Manager (RPM),以及 Duke University 物理系最初为管理 Red Hat Linux 系统开发的 Yellowdog Updater Modified (YUM)。可以使用本文中的资料来准备 Linux 系统管理员认证的 LPI 101 考试,或者只是为了了解添加新软件并及时更新系统的最佳方法。

查看本系列更多内容

|

1 评论:

Ian Shields, 资深程序员, EMC

关闭 [x]

Ian ShieldsIan Shields 参与 developerWorks Linux 专区的许多 Linux 项目。他是 IBM 北卡罗来纳州 Research Triangle Park 的一名高级程序员。他于 1973 年作为一名系统工程师加入 IBM 位于澳大利亚堪培拉的子公司。此后,在加拿大蒙特利尔和北卡罗来纳州 RTP 从事通信系统和普适计算。他拥有多项专利并发表了许多论文。他毕业于 Australian National University,取得纯数学和哲学学位。他拥有北卡罗来纳州州立大学的计算机硕士和博士学位。更多信息参见 My developerWorks 上 Ian 的个人信息。

developerWorks 投稿作者

2010 年 6 月 12 日

关于本系列

本系列文章帮助您学习 Linux 系统管理任务相关知识。您可以使用本系列文章中的资料准备 Linux Professional Institute Certification 级别 1 (LPIC-1)考试 。

请参见我们的 学习 Linux,101:LPIC-1 路线图,查看本系列中各文章的介绍和链接。该路线图目前仍然在更新中,目前反映的最新内容是 LPIC-1 考试的最新目标(2009 年 4 月):在我们完成文章后,我们会将其添加到路线图中。但是,与此同时,您可以在我们的 LPI 认证考试准备教程 中找到类似资料的早期版本,这些内容支持 2009 年 4 月以前发布的 LPIC-1 目标。

概述

在本文中,学习如何在 Linux 系统上使用 RPM 和 YUM 包管理工具管理包。学习:

  • 使用 RPM 和 YUM 安装、卸载、升级和删除包
  • 获取版本、状态、依赖关系、完整性和签名等 RPM 包相关信息
  • 判断一个包提供哪些文件,查明某个文件来自哪个包

本文帮助您准备 Linux Professional Institute’s Junior Level Administration (LPIC-1) 考试 101 中主题 102 下的目标 102.5。该目标的权值为 3。

先决条件

为了最有效地利用本系列中的文章,您应该具有基本的 Linux 知识,并需要准备一个 Linux 系统,用于练习本文介绍的命令。有时候不同版本的程序输出格式不同,因此您所得到的结果未必总是与这里所示的清单和图相同。特别是,许多输出高度依赖于系统上已经安装的包。您自己的输出可能很不一样,但是应该能够看出重要的共同点。


包管理简介

联系 Ian

Ian 是我们最受欢迎、最高产的作者之一。阅读 Ian 在 developerWorks 上发表的所有文章。查看 Ian 的个人信息,与 Ian、其他作者和 My developerWorks 的其他读者联系。

过去,许多 Linux 程序以源代码的形式发行,用户把源代码构建为所需的程序或程序集;源代码还附带必需的手册页、配置文件等等。现在,大多数 Linux 发行商使用称为 的预构建的程序或程序集,包便于在发行版上安装。在本文中,学习帮助安装、更新和删除包的包管理 工具。本文主要关注 Red Hat 开发的 Red Hat Package Manager (RPM),以及 Duke University 物理系最初为管理 Red Hat Linux 系统开发的 Yellowdog Updater Modified (YUM)。本系列中的另一篇文章 “学习 Linux,101:Debian 包管理” 讨论 Debian 系统上使用的包管理工具。

从用户的角度来说,基本的包管理功能由命令提供。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 --helpwhich gcltype gcl。但是,如果系统无法找到 gcl,您可能会看到与清单 1 相似的输出。

清单 1. 没有找到 gcl 命令
[ian@echidna ~]$ gcl --help</p><p>bash: gcl: command not found</p><p>[ian@echidna ~]$ which gcl</p><p>/usr/bin/which: no gcl in (/usr/lib64/qt-3.3/bin:/usr/kerberos/sbin:/usr/kerber</p><p>os/bin:/usr/lib64/ccache:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/</p><p>sbin:/home/ian/bin)</p><p>[ian@echidna ~]$ type gcl</p><p>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</p><p>error: Failed dependencies:</p><p>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 ~]# <strong>yum install gcl</strong></p><p>Loaded plugins: presto, refresh-packagekit</p><p>Setting up Install Process</p><p>Resolving Dependencies</p><p>--&gt; Running transaction check</p><p>---&gt; Package gcl.x86_64 0:2.6.8-0.7.20100201cvs.fc12 set to be updated</p><p>--&gt; Processing Dependency: gcl-selinux for package: gcl-2.6.8-0.7.20100201cvs.fc12.x86_64</p><p>--&gt; Running transaction check</p><p>---&gt; Package gcl-selinux.x86_64 0:2.6.8-0.7.20100201cvs.fc12 set to be updated</p><p>--&gt; Finished Dependency Resolution</p><p>Dependencies Resolved</p><p>=====================================================================================</p><p> Package           Arch         Version                          Repository     Size</p><p>=====================================================================================</p><p>Installing:</p><p> gcl               x86_64       2.6.8-0.7.20100201cvs.fc12       updates       6.3 M</p><p>Installing for dependencies:</p><p> gcl-selinux       x86_64       2.6.8-0.7.20100201cvs.fc12       updates        17 k</p><p>Transaction Summary</p><p>=====================================================================================</p><p>Install       2 Package(s)</p><p>Upgrade       0 Package(s)</p><p>Total download size: 6.4 M</p><p>Installed size: 40 M</p><p>Is this ok [y/N]: <strong>y</strong></p><p>Downloading Packages:</p><p>Setting up and reading Presto delta metadata</p><p>updates/prestodelta                                           | 964 kB     00:01     </p><p>Processing delta metadata</p><p>Package(s) data still to download: 6.4 M</p><p>(1/2): gcl-2.6.8-0.7.20100201cvs.fc12.x86_64.rpm              | 6.3 MB     00:12     </p><p>(2/2): gcl-selinux-2.6.8-0.7.20100201cvs.fc12.x86_64.rpm      |  17 kB     00:00     </p><p>-------------------------------------------------------------------------------------</p><p>Total                                                398 kB/s | 6.4 MB     00:16     </p><p>Running rpm_check_debug</p><p>Running Transaction Test</p><p>Transaction Test Succeeded</p><p>Running Transaction</p><p>  Installing     : gcl-selinux-2.6.8-0.7.20100201cvs.fc12.x86_64                 1/2 </p><p>  Installing     : gcl-2.6.8-0.7.20100201cvs.fc12.x86_64                         2/2 </p><p>Installed:</p><p>  gcl.x86_64 0:2.6.8-0.7.20100201cvs.fc12                                            </p><p>Dependency Installed:</p><p>  gcl-selinux.x86_64 0:2.6.8-0.7.20100201cvs.fc12                                    </p><p>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 ~]$ <strong>cat /etc/yum.repos.d/fedora-updates.repo</strong></p><p>[updates]</p><p>name=Fedora $releasever - $basearch - Updates</p><p>failovermethod=priority</p><p>#baseurl=http://download.fedoraproject.org/pub/fedora/linux/updates/$releasever</p><p>/$basearch/</p><p>mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=updates-released-f$r</p><p>eleasever&amp;arch=$basearch</p><p>enabled=1</p><p>gpgcheck=1</p><p>gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-$basearch</p><p>[updates-debuginfo]</p><p>name=Fedora $releasever - $basearch - Updates - Debug</p><p>failovermethod=priority</p><p>#baseurl=http://download.fedoraproject.org/pub/fedora/linux/updates/$releasever</p><p>/$basearch/debug/</p><p>mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=updates-released-deb</p><p>ug-f$releasever&amp;arch=$basearch</p><p>enabled=0</p><p>gpgcheck=1</p><p>gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-$basearch</p><p>[updates-source]</p><p>name=Fedora $releasever - Updates Source</p><p>failovermethod=priority</p><p>#baseurl=http://download.fedoraproject.org/pub/fedora/linux/updates/$releasever</p><p>/SRPMS/</p><p>mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=updates-released-sou</p><p>rce-f$releasever&amp;arch=$basearch</p><p>enabled=0</p><p>gpgcheck=1</p><p>gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-$basearch

YUM 和 RPM 使用本地数据库判断安装的包。本地数据库中存储的包元数据是从启用的存储库获取的。尽管很少需要为本地数据库操心,但是可以使用 yum clean 命令清除本地存储的信息的不同部分,使用 yum makecache 在本地数据库中为启用的 repo 创建信息。例如,如果修改了 repo 配置,就可能需要这么做。


删除 RPM 包

如果要删除包,可以使用 yumremove 选项或 rpm-e 选项。使用 rpm -e 删除 gcl 的试运行见清单 5。如果可以删除这个包,就不会有输出。

清单 5. 试删除 gcl
[root@echidna ~]# <strong>rpm -e --test gcl</strong>

与使用 apt-get 模拟删除 Debian 包不同,RPM 系统并不维护自动安装的包的相关信息,所以无法通过试删除查明哪些依赖包也可以删除。但是,如果在单一命令中指定多个要删除的包,那么没有依赖关系的包会先于有依赖关系的包删除。

与安装包不同,当使用 rpm 删除包时,在删除包之前没有提示。但是,如果试图删除其他包需要的包,它不会执行删除操作,您会看到清单 6 所示的错误消息。

清单 6. 用 rpm 删除依赖包
[root@echidna ~]# <strong>rpm -e gcl-selinux</strong></p><p>error: Failed dependencies:</p><p>	gcl-selinux is needed by (installed) gcl-2.6.8-0.7.20100201cvs.fc12.x86_64

如果使用 yum remove,在执行事务测试之后会显示提示。如果试图删除的包是其他已安装包的依赖包,YUM 会提议删除这些包和依赖包,见清单 7。

清单 7. 用 yum 删除依赖包
[root@echidna ~]# <strong>yum remove gcl-selinux</strong></p><p>Loaded plugins: presto, refresh-packagekit</p><p>Setting up Remove Process</p><p>Resolving Dependencies</p><p>--&gt; Running transaction check</p><p>---&gt; Package gcl-selinux.x86_64 0:2.6.8-0.7.20100201cvs.fc12 set to be erased</p><p>--&gt; Processing Dependency: gcl-selinux for package: gcl-2.6.8-0.7.20100201cvs.fc12.x86_64</p><p>--&gt; Running transaction check</p><p>---&gt; Package gcl.x86_64 0:2.6.8-0.7.20100201cvs.fc12 set to be erased</p><p>--&gt; Finished Dependency Resolution</p><p>Dependencies Resolved</p><p>=====================================================================================</p><p> Package          Arch        Version                            Repository     Size</p><p>=====================================================================================</p><p>Removing:</p><p> gcl-selinux      x86_64      2.6.8-0.7.20100201cvs.fc12         @updates       90 k</p><p>Removing for dependencies:</p><p> gcl              x86_64      2.6.8-0.7.20100201cvs.fc12         @updates       40 M</p><p>Transaction Summary</p><p>=====================================================================================</p><p>Remove        2 Package(s)</p><p>Reinstall     0 Package(s)</p><p>Downgrade     0 Package(s)</p><p>Is this ok [y/N]: <strong>n</strong></p><p>Exiting on user Command</p><p>Complete!

升级 RPM 包

既然已经了解了如何安装和删除 RPM,我们来看看如何把 RPM 包升级到更高级别。可以使用 yum update 更新整个系统,还可以指定单一包或通配符。清单 8 说明如何更新所有名称以 “gr” 开头的包。注意,这里使用撇号防止 shell 展开 “*”。

清单 8. 使用 yum update 执行更新
[root@echidna ~]# <strong>yum update 'gr*'</strong></p><p>Loaded plugins: presto, refresh-packagekit</p><p>Setting up Update Process</p><p>Resolving Dependencies</p><p>--&gt; Running transaction check</p><p>---&gt; Package grep.x86_64 0:2.6.3-1.fc12 set to be updated</p><p>---&gt; Package groff.x86_64 0:1.18.1.4-20.fc12 set to be updated</p><p>--&gt; Finished Dependency Resolution</p><p>Dependencies Resolved</p><p>=====================================================================================</p><p> Package         Arch             Version                    Repository         Size</p><p>=====================================================================================</p><p>Updating:</p><p> grep            x86_64           2.6.3-1.fc12               updates           228 k</p><p> groff           x86_64           1.18.1.4-20.fc12           updates           1.5 M</p><p>Transaction Summary</p><p>=====================================================================================</p><p>Install       0 Package(s)</p><p>Upgrade       2 Package(s)</p><p>Total download size: 1.7 M</p><p>Is this ok [y/N]: <strong>y</strong></p><p>Downloading Packages:</p><p>Setting up and reading Presto delta metadata</p><p>Processing delta metadata</p><p>Download delta size: 854 k</p><p>http://fedora.fastsoft.net/pub/linux/fedora/linux/updates/12/x86_64/drpms/grep-2.5.3-</p><p>6.fc12_2.6.3-1.fc12.x86_64.drpm: [Errno 14] HTTP Error 404 : http://fedora.fastsoft.n</p><p>et/pub/linux/fedora/linux/updates/12/x86_64/drpms/grep-2.5.3-6.fc12_2.6.3-1.fc12.x86_</p><p>64.drpm </p><p>Trying other mirror.</p><p>(1/2): grep-2.5.3-6.fc12_2.6.3-1.fc12.x86_64.drpm             | 214 kB     00:00     </p><p>(2/2): groff-1.18.1.4-18.fc12_1.18.1.4-20.fc12.x86_64.drpm    | 640 kB     00:00     </p><p>Finishing rebuild of rpms, from deltarpms</p><p>&lt;delta rebuild&gt;                                               | 1.7 MB     00:02     </p><p>Presto reduced the update size by 52% (from 1.7 M to 854 k).</p><p>Running rpm_check_debug</p><p>Running Transaction Test</p><p>Transaction Test Succeeded</p><p>Running Transaction</p><p>  Updating       : grep-2.6.3-1.fc12.x86_64                                      1/4 </p><p>  Updating       : groff-1.18.1.4-20.fc12.x86_64                                 2/4 </p><p>  Cleanup        : grep-2.5.3-6.fc12.x86_64                                      3/4 </p><p>  Cleanup        : groff-1.18.1.4-18.fc12.x86_64                                 4/4 </p><p>Updated:</p><p>  grep.x86_64 0:2.6.3-1.fc12             groff.x86_64 0:1.18.1.4-20.fc12            </p><p>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 ~]# <strong>ls *.rpm</strong></p><p>vim-common-7.2.411-1.fc12.x86_64.rpm  vim-enhanced-7.2.411-1.fc12.x86_64.rpm</p><p>[root@echidna ~]# <strong>rpm -Uvh *.rpm http://mirrors.usc.edu/pub/linux/distributions\</strong></p><p>&gt; <strong>/fedora/linux/updates/12/x86_64/vim-minimal-7.2.411-1.fc12.x86_64.rpm</strong></p><p>Retrieving http://mirrors.usc.edu/pub/linux/distributions/fedora/linux/updates/12/x86</p><p>_64/vim-minimal-7.2.411-1.fc12.x86_64.rpm</p><p>Preparing...                ########################################### [100%]</p><p>   1:vim-common             ########################################### [ 33%]</p><p>   2:vim-enhanced           ########################################### [ 67%]</p><p>   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 ~]$ <strong>yum list gcl</strong></p><p>Loaded plugins: presto, refresh-packagekit</p><p>Installed Packages</p><p>gcl.x86_64                  2.6.8-0.7.20100201cvs.fc12                  @updates</p><p>[ian@echidna ~]$ <strong>rpm -q gcl</strong></p><p>gcl-2.6.8-0.7.20100201cvs.fc12.x86_64</p><p>[ian@echidna ~]$ <strong>yum info gcl</strong></p><p>Loaded plugins: presto, refresh-packagekit</p><p>Installed Packages</p><p>Name       : gcl</p><p>Arch       : x86_64</p><p>Version    : 2.6.8</p><p>Release    : 0.7.20100201cvs.fc12</p><p>Size       : 40 M</p><p>Repo       : installed</p><p>From repo  : updates</p><p>Summary    : GNU Common Lisp</p><p>URL        : http://www.gnu.org/software/gcl/</p><p>License    : GPL+ and LGPLv2+</p><p>Description: GCL is a Common Lisp currently compliant with the ANSI standard.</p><p>           : Lisp compilation produces native code through the intermediary of</p><p>           : the system's C compiler, from which GCL derives efficient</p><p>           : performance and facile portability. Currently uses TCL/Tk as GUI.</p><p>[ian@echidna ~]$ <strong>rpm -qi gcl</strong></p><p>Name        : gcl                          Relocations: (not relocatable)</p><p>Version     : 2.6.8                             Vendor: Fedora Project</p><p>Release     : 0.7.20100201cvs.fc12          Build Date: Tue 23 Mar 2010 03:20:36 PM EDT</p><p>Install Date: Wed 05 May 2010 01:01:34 PM EDT      Build Host: x86-02.phx2.fedoraproject.</p><p>org</p><p>Group       : Development/Languages         Source RPM: gcl-2.6.8-0.7.20100201cvs.fc12.sr</p><p>c.rpm</p><p>Size        : 41667750                         License: GPL+ and LGPLv2+</p><p>Signature   : RSA/8, Tue 23 Mar 2010 04:14:06 PM EDT, Key ID 9d1cc34857bbccba</p><p>Packager    : Fedora Project</p><p>URL         : http://www.gnu.org/software/gcl/</p><p>Summary     : GNU Common Lisp</p><p>Description :</p><p>GCL is a Common Lisp currently compliant with the ANSI standard.  Lisp</p><p>compilation produces native code through the intermediary of the</p><p>system's C compiler, from which GCL derives efficient performance and</p><p>facile portability. Currently uses TCL/Tk as GUI.

详细的清单显示与 RPM 包相关联的一些标记。注意,rpmyum 以不同的格式显示不同的信息。在本文中,我们都使用标准命令选项提供的基本输出。如果希望使用 rpm --queryformat 选项定制查询输出,请参考手册页。如果希望了解您的 rpm 版本支持的所有标记,应该运行 rpm --querytags

如清单 10 所示,可以使用 yum 列出安装的包。还可以用它列出有更新可用的包、可以安装的包以及具有其他性质的包,比如废弃的包或存储库中最近添加的包。甚至可以使用 yum 搜索包。在清单 11 中可以看到,texmacs 包还没有安装,但是可以从 fedora 存储库获取它。如果搜索 “texmacs”,会看到提到它的四个包。很容易看出为什么会找到 TeXmacs* 包。使用 yum info pydot 查明为什么也会找到 pydot 包。

清单 11. 搜索 “texmacs”
[ian@echidna ~]$ <strong>yum list texmacs</strong></p><p>Loaded plugins: presto, refresh-packagekit</p><p>Available Packages</p><p>TeXmacs.x86_64                         1.0.7.2-2.fc12                          fedora</p><p>[ian@echidna ~]$ <strong>yum search texmacs</strong></p><p>Loaded plugins: presto, refresh-packagekit</p><p>================================= Matched: texmacs ==================================</p><p>TeXmacs-devel.i686 : Development files for TeXmacs</p><p>TeXmacs-devel.x86_64 : Development files for TeXmacs</p><p>TeXmacs.x86_64 : Structured wysiwyg scientific text editor</p><p>pydot.noarch : Python interface to Graphviz's Dot language

对于后面的查询示例,我们主要使用 rpm,因为它的选项更丰富。许多示例也可以使用 yum 完成,yum 有一些基本 rpm 选项不具备的功能。更多信息参见手册页。

RPM 包和其中的文件

用户常常希望知道一个包中有哪些文件,或者某个文件来自哪个包。使用 -ql 选项列出 gcl 包中的文件,见清单 12。这个包中有许多文件,所以这里只给出部分输出。

清单 12. 显示 gcl 包中的文件
[ian@echidna ~]$ <strong>rpm -ql gcl</strong></p><p>/usr/bin/gcl</p><p>/usr/lib/gcl-2.6.8</p><p>/usr/lib/gcl-2.6.8/clcs</p><p>/usr/lib/gcl-2.6.8/clcs/sys-proclaim.lisp</p><p>/usr/lib/gcl-2.6.8/cmpnew</p><p>/usr/lib/gcl-2.6.8/cmpnew/gcl_cmpmain.lsp</p><p>/usr/lib/gcl-2.6.8/cmpnew/gcl_cmpopt.lsp</p><p>/usr/lib/gcl-2.6.8/cmpnew/gcl_collectfn.lsp</p><p>.</p><p>.</p><p>.</p><p>/usr/share/info/gcl-tk.info.gz</p><p>/usr/share/info/gcl.info-1.gz</p><p>/usr/share/info/gcl.info-2.gz</p><p>/usr/share/info/gcl.info-3.gz</p><p>/usr/share/info/gcl.info-4.gz</p><p>/usr/share/info/gcl.info-5.gz</p><p>/usr/share/info/gcl.info-6.gz</p><p>/usr/share/info/gcl.info-7.gz</p><p>/usr/share/info/gcl.info-8.gz</p><p>/usr/share/info/gcl.info-9.gz</p><p>/usr/share/info/gcl.info.gz</p><p>/usr/share/man/man1/gcl.1.gz

通过在查询中添加 -c 选项,可以把列出的文件限制为配置文件。-d 选项把输出限制为文档文件。

查询包文件

上面的包查询命令在 RPM 数据库中查询已经安装的包。如果刚下载了一个包,想获取同类信息,可以在查询中使用 -p(代表包文件)选项并指定包的文件 名(与安装包时一样)。清单 13 显示前面下载的两个 vim 包的信息。我们只作为根用户运行它,因为文件在根用户的主目录中。可以添加其他查询选项,比如用 -l 列出文件,用 -i 列出信息。

清单 13. 显示两个 vim 包的包文件信息
[root@echidna ~]# rpm -qp *.rpm</p><p>vim-common-7.2.411-1.fc12.x86_64</p><p>vim-enhanced-7.2.411-1.fc12.x86_64

查询安装的所有包

-a 选项把查询应用于安装的所有包。这会生成许多输出,所以通常同时使用一个或多个筛选器,比如用 sort 进行排序,用 moreless 进行分页输出,用 wc 获取包或文件内容,用 grep 搜索您不确定名称的包。清单 14 给出以下查询:

  1. 系统上所有包的排序列表
  2. 系统上所有包的数量
  3. 系统上所有包中的所有文件的数量
  4. 用 RPM 安装的所有文档文件的数量
  5. 搜索名称中包含 “gcl” 的所有包(区分大小写)
清单 14. 对所有包执行查询
[ian@echidna ~]$ <strong>rpm -qa | sort | more</strong></p><p>aalib-libs-1.4.0-0.18.rc5.fc12.x86_64</p><p>abrt-1.0.8-2.fc12.x86_64</p><p>abrt-addon-ccpp-1.0.8-2.fc12.x86_64</p><p>abrt-addon-kerneloops-1.0.8-2.fc12.x86_64</p><p>abrt-addon-python-1.0.8-2.fc12.x86_64</p><p>abrt-desktop-1.0.8-2.fc12.x86_64</p><p>abrt-gui-1.0.8-2.fc12.x86_64</p><p>abrt-libs-1.0.8-2.fc12.x86_64</p><p>abrt-plugin-bugzilla-1.0.8-2.fc12.x86_64</p><p>abrt-plugin-logger-1.0.8-2.fc12.x86_64</p><p>abrt-plugin-runapp-1.0.8-2.fc12.x86_64</p><p>abyssinica-fonts-1.0-5.fc12.noarch</p><p>acl-2.2.49-2.fc12.x86_64</p><p>...</p><p>[ian@echidna ~]$ <strong>rpm -qa | wc -l</strong></p><p>1792</p><p>[ian@echidna ~]$ <strong>rpm -qal | wc -l</strong></p><p>281052</p><p>[ian@echidna ~]$ <strong>rpm -qad | wc -l</strong></p><p>45686</p><p>[ian@echidna ~]$ <strong>rpm -qa | grep -i gcl</strong></p><p>gcl-selinux-2.6.8-0.7.20100201cvs.fc12.x86_64</p><p>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 ~]$ <strong>which vim</strong></p><p>/usr/bin/vim</p><p>[ian@echidna ~]$ <strong>rpm -qf `which vim`</strong></p><p>vim-enhanced-7.2.411-1.fc12.x86_64</p><p>[ian@echidna ~]$ <strong>rpm -qf $(which vim)</strong></p><p>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 ~]$ <strong>rpm -qR gcl</strong></p><p>/bin/sh  </p><p>/bin/sh  </p><p>/bin/sh  </p><p>/sbin/install-info  </p><p>/sbin/install-info  </p><p>gcl-selinux  </p><p>libX11.so.6()(64bit)  </p><p>libc.so.6()(64bit)  </p><p>libc.so.6(GLIBC_2.11)(64bit)  </p><p>libc.so.6(GLIBC_2.2.5)(64bit)  </p><p>libc.so.6(GLIBC_2.3)(64bit)  </p><p>libc.so.6(GLIBC_2.3.4)(64bit)  </p><p>libc.so.6(GLIBC_2.4)(64bit)  </p><p>libc.so.6(GLIBC_2.7)(64bit)  </p><p>libc.so.6(GLIBC_2.8)(64bit)  </p><p>libdl.so.2()(64bit)  </p><p>libgmp.so.3()(64bit)  </p><p>libm.so.6()(64bit)  </p><p>libm.so.6(GLIBC_2.2.5)(64bit)  </p><p>libreadline.so.6()(64bit)  </p><p>libtcl8.5.so()(64bit)  </p><p>libtk8.5.so()(64bit)  </p><p>libz.so.1()(64bit)  </p><p>rpmlib(CompressedFileNames) &lt;= 3.0.4-1</p><p>rpmlib(FileDigests) &lt;= 4.6.0-1</p><p>rpmlib(PayloadFilesHavePrefix) &lt;= 4.0-1</p><p>rtld(GNU_HASH)  </p><p>rpmlib(PayloadIsXz) &lt;= 5.2-1

把功能与提供它们的包联系起来不太容易。带 deplist 选项的 yum 命令可以提供帮助。如果只指定包名,没有版本号,可能会得到其他已知版本的列表。清单 17 说明如何获得安装的 gcl 版本的依赖列表。

清单 17. 使用 yum deplist 查明 gcl 需要什么
[ian@echidna ~]$ <strong>yum deplist $(rpm -q gcl)</strong></p><p>Loaded plugins: presto, refresh-packagekit</p><p>Finding dependencies: </p><p>package: gcl.x86_64 2.6.8-0.7.20100201cvs.fc12</p><p>  dependency: libc.so.6(GLIBC_2.3.4)(64bit)</p><p>   provider: glibc.x86_64 2.11-2</p><p>   provider: glibc.x86_64 2.11.1-6</p><p>  dependency: gcl-selinux</p><p>   provider: gcl-selinux.x86_64 2.6.8-0.6.20090701cvs.fc12</p><p>   provider: gcl-selinux.x86_64 2.6.8-0.7.20100201cvs.fc12</p><p>  dependency: libgmp.so.3()(64bit)</p><p>   provider: gmp.x86_64 4.3.1-5.fc12</p><p>  dependency: libc.so.6(GLIBC_2.8)(64bit)</p><p>   provider: glibc.x86_64 2.11-2</p><p>   provider: glibc.x86_64 2.11.1-6</p><p>  dependency: libc.so.6(GLIBC_2.4)(64bit)</p><p>   provider: glibc.x86_64 2.11-2</p><p>   provider: glibc.x86_64 2.11.1-6</p><p>  dependency: libc.so.6()(64bit)</p><p>   provider: glibc.x86_64 2.11-2</p><p>   provider: glibc.x86_64 2.11.1-6</p><p>  dependency: /sbin/install-info</p><p>   provider: info.x86_64 4.13a-7.fc12</p><p>   provider: info.x86_64 4.13a-9.fc12</p><p>  dependency: libX11.so.6()(64bit)</p><p>   provider: libX11.x86_64 1.3-1.fc12</p><p>  dependency: libc.so.6(GLIBC_2.7)(64bit)</p><p>   provider: glibc.x86_64 2.11-2</p><p>   provider: glibc.x86_64 2.11.1-6</p><p>  dependency: libtcl8.5.so()(64bit)</p><p>   provider: tcl.x86_64 1:8.5.7-4.fc12</p><p>   provider: tcl.x86_64 1:8.5.7-5.fc12</p><p>  dependency: libc.so.6(GLIBC_2.11)(64bit)</p><p>   provider: glibc.x86_64 2.11-2</p><p>   provider: glibc.x86_64 2.11.1-6</p><p>  dependency: libtk8.5.so()(64bit)</p><p>   provider: tk.x86_64 1:8.5.7-2.fc12</p><p>   provider: tk.x86_64 1:8.5.7-3.fc12</p><p>  dependency: libc.so.6(GLIBC_2.3)(64bit)</p><p>   provider: glibc.x86_64 2.11-2</p><p>   provider: glibc.x86_64 2.11.1-6</p><p>  dependency: libm.so.6()(64bit)</p><p>   provider: glibc.x86_64 2.11-2</p><p>   provider: glibc.x86_64 2.11.1-6</p><p>  dependency: libz.so.1()(64bit)</p><p>   provider: zlib.x86_64 1.2.3-23.fc12</p><p>  dependency: rtld(GNU_HASH)</p><p>   provider: glibc.i686 2.11-2</p><p>   provider: glibc.x86_64 2.11-2</p><p>   provider: glibc.x86_64 2.11.1-6</p><p>   provider: glibc.i686 2.11.1-6</p><p>  dependency: libdl.so.2()(64bit)</p><p>   provider: glibc.x86_64 2.11-2</p><p>   provider: glibc.x86_64 2.11.1-6</p><p>  dependency: libreadline.so.6()(64bit)</p><p>   provider: readline.x86_64 6.0-3.fc12</p><p>  dependency: /bin/sh</p><p>   provider: bash.x86_64 4.0.33-1.fc12</p><p>   provider: bash.x86_64 4.0.35-3.fc12</p><p>  dependency: libc.so.6(GLIBC_2.2.5)(64bit)</p><p>   provider: glibc.x86_64 2.11-2</p><p>   provider: glibc.x86_64 2.11.1-6</p><p>  dependency: libm.so.6(GLIBC_2.2.5)(64bit)</p><p>   provider: glibc.x86_64 2.11-2</p><p>   provider: glibc.x86_64 2.11.1-6

这个列表还显示每个功能可能的提供者。可以看到大多数依赖功能可以由多个包级别提供。例如,/bin/sh 可以来自 bash 的两个级别之一。通过使用创造性的筛选,可以把输出缩减为清单 18 所示的包名列表。

清单 18. 把 yum deplist 的输出缩减为只列出包名
[ian@echidna ~]$ <strong>yum deplist $(rpm -q gcl) | grep "provider:" | \</strong></p><p>&gt; <strong>awk '{ print $2 }'|sort|uniq</strong></p><p>bash.x86_64</p><p>gcl-selinux.x86_64</p><p>glibc.i686</p><p>glibc.x86_64</p><p>gmp.x86_64</p><p>info.x86_64</p><p>libX11.x86_64</p><p>readline.x86_64</p><p>tcl.x86_64</p><p>tk.x86_64</p><p>zlib.x86_64

如果只想知道需要安装哪些包,可以运行 yum install,查看在提示接受安装提议之前显示的列表。

除了查明包需要的功能之外,还可能需要了解哪个包提供某一功能。前面演示了如何查明哪个包包含某一文件。清单 19 说明如何使用 rpmyum 查明哪个包提供 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)'</p><p>gcl-selinux-2.6.8-0.7.20100201cvs.fc12.x86_64</p><p>[ian@echidna ~]$ yum whatprovides 'gcl-selinux(x86-64)'</p><p>Loaded plugins: presto, refresh-packagekit</p><p>gcl-selinux-2.6.8-0.6.20090701cvs.fc12.x86_64 : SELinux policy for GCL images</p><p>Repo        : fedora</p><p>Matched from:</p><p>Other       : gcl-selinux(x86-64)</p><p>gcl-selinux-2.6.8-0.7.20100201cvs.fc12.x86_64 : SELinux policy for GCL images</p><p>Repo        : updates</p><p>Matched from:</p><p>Other       : gcl-selinux(x86-64)</p><p>gcl-selinux-2.6.8-0.7.20100201cvs.fc12.x86_64 : SELinux policy for GCL images</p><p>Repo        : installed</p><p>Matched from:</p><p>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</p><p>vim-enhanced-7.2.411-1.fc12.x86_64.rpm:</p><p>    Header V3 RSA/SHA256 signature: OK, key ID 57bbccba</p><p>    Header SHA1 digest: OK (f9a199545a515f7ff0716729768b41eb68fe29a8)</p><p>    V3 RSA/SHA256 signature: OK, key ID 57bbccba</p><p>    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 ~]$ <strong>rpm -V vim-common</strong>

现在,我们作为根用户删除 /usr/bin/xxd 并把 /usr/share/vim/vim72/syntax/bindzone.vim 替换为 /bin/bash。然后再次检查。结果见清单 22。

清单 22. 篡改 vim-common 包
[root@echidna ~]# <strong>rpm -qf /usr/bin/xxd /usr/share/vim/vim72/syntax/bindzone.vim</strong></p><p>vim-common-7.2.411-1.fc12.x86_64</p><p>vim-common-7.2.411-1.fc12.x86_64</p><p>[root@echidna ~]# <strong>rm /usr/bin/xxd</strong></p><p>rm: remove regular file `/usr/bin/xxd'? <strong>y</strong></p><p>[root@echidna ~]# <strong>cp /bin/bash /usr/share/vim/vim72/syntax/bindzone.vim</strong></p><p>cp: overwrite `/usr/share/vim/vim72/syntax/bindzone.vim'? <strong>y</strong></p><p>[root@echidna ~]# <strong>rpm -V vim-common</strong></p><p>missing     /usr/bin/xxd</p><p>S.5....T.    /usr/share/vim/vim72/syntax/bindzone.vim

输出表明对 /usr/share/vim/vim72/syntax/bindzone.vim 文件的 MD5 和、文件大小和 mtime 检查失败了。解决这个问题的一种方法是删除这个包,然后重新安装,依赖于 vim-common 的其他已安装包仍然可以正常运行。这个解决方案使用 rpm--force 选项或 yumreinstall 功能强制重新安装。清单 23 演示如何用 yum 重新安装,然后检查包现在是否良好,检查删除的文件是否已经恢复了。

清单 23. 重新安装 vim-common 包
[root@echidna ~]# <strong>yum reinstall vim-common</strong></p><p>Loaded plugins: presto, refresh-packagekit</p><p>Setting up Reinstall Process</p><p>Resolving Dependencies</p><p>--&gt; Running transaction check</p><p>---&gt; Package vim-common.x86_64 2:7.2.411-1.fc12 set to be updated</p><p>--&gt; Finished Dependency Resolution</p><p>Dependencies Resolved</p><p>=====================================================================================</p><p> Package            Arch           Version                     Repository       Size</p><p>=====================================================================================</p><p>Reinstalling:</p><p> vim-common         x86_64         2:7.2.411-1.fc12            updates         6.0 M</p><p>Transaction Summary</p><p>=====================================================================================</p><p>Remove        0 Package(s)</p><p>Reinstall     1 Package(s)</p><p>Downgrade     0 Package(s)</p><p>Total download size: 6.0 M</p><p>Installed size: 17 M</p><p>Is this ok [y/N]: <strong>y</strong></p><p>Downloading Packages:</p><p>Setting up and reading Presto delta metadata</p><p>updates/prestodelta                                           | 969 kB     00:00     </p><p>Processing delta metadata</p><p>Package(s) data still to download: 6.0 M</p><p>vim-common-7.2.411-1.fc12.x86_64.rpm                          | 6.0 MB     00:01     </p><p>Running rpm_check_debug</p><p>Running Transaction Test</p><p>Transaction Test Succeeded</p><p>Running Transaction</p><p>Warning: RPMDB altered outside of yum.</p><p>  Installing     : 2:vim-common-7.2.411-1.fc12.x86_64                            1/1 </p><p>Installed:</p><p>  vim-common.x86_64 2:7.2.411-1.fc12                                                 </p><p>Complete!</p><p>[root@echidna ~]# <strong>rpm -V vim-common</strong></p><p>[root@echidna ~]# <strong>ls /usr/bin/xxd</strong></p><p>/usr/bin/xxd

如果需要更有力的措施

包管理系统通常可以恢复包。但是,如果删除了包中的重要文件,重新安装包但不删除无法解决问题,那么可能需要在重新安装之前删除包。对于这种情况,可能希望删除现有的拷贝并重新安装,但是不希望卸载和重新安装依赖它的所有包。为此,在删除包时,可以使用 rpm 命令的 --nodeps 选项绕过依赖关系检查。在清单 24 中,删除了 vim-common 中的 /usr/bin/xxd 文件,然后演示如何恢复这个包。

清单 24. 用 rpm 更新包
[root@echidna ~]# <strong>rm /usr/bin/xxd</strong></p><p>rm: remove regular file `/usr/bin/xxd'? <strong>y</strong></p><p>[root@echidna ~]# <strong># Oops! we needed that file</strong></p><p>[root@echidna ~]# <strong>rpm -Fvh vim-common-7.2.411-1.fc12.x86_64.rpm </strong></p><p>[root@echidna ~]# <strong>ls /usr/bin/xxd</strong></p><p>ls: cannot access /usr/bin/xxd: No such file or directory</p><p>[root@echidna ~]# <strong># Oh! Freshening the package didn't replace the missing file</strong></p><p>[root@echidna ~]# <strong>rpm -e vim-common</strong></p><p>error: Failed dependencies:</p><p>	vim-common = 2:7.2.411-1.fc12 is needed by (installed) vim-enhanced-2:7.2.411-1.f</p><p>c12.x86_64</p><p>[root@echidna ~]# <strong># Can't remove vim-common because vim-enhanced needs it</strong></p><p>[root@echidna ~]# <strong>rpm -e --nodeps vim-common</strong></p><p>[root@echidna ~]# <strong># Bypassing the dependency check allowed removal</strong></p><p>[root@echidna ~]# <strong>rpm -Uvh vim-common-7.2.411-1.fc12.x86_64.rpm </strong></p><p>Preparing...                ########################################### [100%]</p><p>   1:vim-common             ########################################### [100%]</p><p>[root@echidna ~]# <strong># Update (or install) vim-common again</strong></p><p>[root@echidna ~]# <strong>ls /usr/bin/xxd</strong></p><p>/usr/bin/xxd</p><p>[root@echidna ~]# <strong># And /usr/bin/xxd is back</strong>

现在,如果发生意外或一般的更新失败,您可以以几种方法更新或修复。注意,在安装 RPM 时也可以绕过依赖关系检查,但是这通常不是好做法。


从存储库下载 RPM

尽管 yum 会自动地从存储库获取包,但是您可能希望下载并保存 RPM,比如为了在不连网的系统上安装它们、为了检查它们的内容或有其他原因。可以使用清单 25 所示的 yumdownloader 命令。对于我们的示例,这个包已经安装了,所以没有要下载的包。如果有这样的包,可以使用 --resolve 选项再次下载它们。

清单 25. 下载 gcl 包
[ian@echidna ~]$ yumdownloader --resolve gcl</p><p>Loaded plugins: presto, refresh-packagekit</p><p>adobe-linux-i386                                                               17/17</p><p>--&gt; Running transaction check</p><p>---&gt; Package gcl.x86_64 0:2.6.8-0.7.20100201cvs.fc12 set to be updated</p><p>--&gt; Finished Dependency Resolution</p><p>gcl-2.6.8-0.7.20100201cvs.fc12.x86_64.rpm                     | 6.3 MB     00:01

使用 rpm2cpio

如果下载一个 RPM,需要检查它的内容而不是安装它,可以使用 rpm2cpio 命令把内容转换为 cpio 存档,然后通过 cpio 命令提取出包中的某些或所有文件。清单 26 对 gcl-selinux 包执行转换,然后显示提取出的文件(和目录)。关于 rpm2cpiocpio 命令的更多信息参见它们的手册页。

清单 26. 用 rpm2cpio 提取 gcl-selinux 包
[ian@echidna ~]$ <strong>yumdownloader gcl-selinux</strong></p><p>Loaded plugins: presto, refresh-packagekit</p><p>gcl-selinux-2.6.8-0.7.20100201cvs.fc12.x86_64.rpm        |  17 kB     00:00     </p><p>[ian@echidna ~]$ <strong>mkdir gcl-selinux</strong></p><p>[ian@echidna ~]$ <strong>cd gcl-selinux</strong></p><p>[ian@echidna gcl-selinux]$ <strong>rpm2cpio ../gcl-selinux*.rpm | cpio -idv</strong></p><p>./usr/share/selinux/packages/gcl</p><p>./usr/share/selinux/packages/gcl/gcl.pp</p><p>182 blocks</p><p>[ian@echidna gcl-selinux]$ <strong>find .</strong></p><p>.</p><p>./usr</p><p>./usr/share</p><p>./usr/share/selinux</p><p>./usr/share/selinux/packages</p><p>./usr/share/selinux/packages/gcl</p><p>./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 ~]# <strong>yum search command-not-found</strong></p><p>Loaded plugins: presto, refresh-packagekit</p><p>========================== Matched: command-not-found ==========================</p><p>PackageKit-command-not-found.x86_64 : Ask the user to install command line</p><p>                                    : programs automatically</p><p>You have new mail in /var/spool/mail/root</p><p>[root@echidna ~]# <strong>yum install PackageKit-command-not-found.x86_64</strong></p><p>Loaded plugins: presto, refresh-packagekit</p><p>Setting up Install Process</p><p>Resolving Dependencies</p><p>--&gt; Running transaction check</p><p>---&gt; Package PackageKit-command-not-found.x86_64 0:0.5.7-2.fc12 set to be updated</p><p>--&gt; Finished Dependency Resolution</p><p>Dependencies Resolved</p><p>================================================================================</p><p> Package                          Arch       Version          Repository   Size</p><p>================================================================================</p><p>Installing:</p><p> PackageKit-command-not-found     x86_64     0.5.7-2.fc12     updates     102 k</p><p>Transaction Summary</p><p>================================================================================</p><p>Install       1 Package(s)</p><p>Upgrade       0 Package(s)</p><p>Total download size: 102 k</p><p>Installed size: 262 k</p><p>Is this ok [y/N]: y</p><p>Downloading Packages:</p><p>Setting up and reading Presto delta metadata</p><p>Processing delta metadata</p><p>Package(s) data still to download: 102 k</p><p>PackageKit-command-not-found-0.5.7-2.fc12.x86_64.rpm     | 102 kB     00:00     </p><p>Running rpm_check_debug</p><p>Running Transaction Test</p><p>Transaction Test Succeeded</p><p>Running Transaction</p><p>  Installing     : PackageKit-command-not-found-0.5.7-2.fc12.x86_64         1/1 </p><p>Installed:</p><p>  PackageKit-command-not-found.x86_64 0:0.5.7-2.fc12                            </p><p>Complete!

清单 28 说明在安装 PackageKit-command-not-found 之后如何定义这个函数。如果函数无法执行搜索,那么它模拟标准的系统行为,返回 127。

清单 28. command_not_found_handle
[ian@echidna ~]$ <strong>type command_not_found_handle</strong></p><p>command_not_found_handle is a function</p><p>command_not_found_handle () </p><p>{ </p><p>    runcnf=1;</p><p>    retval=127;</p><p>    [ ! -S /var/run/dbus/system_bus_socket ] &amp;&amp; runcnf=0;</p><p>    [ ! -x /usr/sbin/packagekitd ] &amp;&amp; runcnf=0;</p><p>    if [ $runcnf -eq 1 ]; then</p><p>        /usr/libexec/pk-command-not-found $1;</p><p>        retval=$?;</p><p>    else</p><p>        echo "bash: $1: command not found";</p><p>    fi;</p><p>    return $retval</p><p>}

如果在 清单 1 中运行 gcl 之前安装了这个功能,可能会看到清单 29 所示的输出。

清单 29. 安装 command_not_found_handle 之后尝试运行 gcl
[ian@echidna ~]$ <strong>gcl</strong></p><p>Command not found. Install package 'gcl' to provide command 'gcl'? [N/y]

其他工具

除了 yumrpm 之外,发行商可能提供了用于从存储库安装包或更新整个系统的其他工具。这些工具可能是图形化工具或命令行工具,或者同时提供这两种界面。例如:

  • 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 图形界面

Fedora 12 (Gnome) 上 Software Update 图形界面的屏幕图

除了这里讨论的内容,RPM 和 YUM 包管理系统还有许多特性。更多信息参见 参考资料 中的链接。

参考资料

学习

  • 使用 学习 Linux,101:LPIC-1 路线图 找到帮助您准备基于 2009 年 4 月目标的 LPIC-1 认证的 developerWorks 文章。

  • 在 LPIC Program 站点中,可以找到 Linux Professional Institute 的三个 Linux 系统管理认证级别的具体目标、任务列表、样例问题。具体请参见 2009 年 4 月的 LPI 考试 101 和 LPI 考试 102 目标。请随时关注 LPIC Program 站点,以便了解最新目标。

  • 回顾 developerWorks 上的整个 LPI 考试准备系列,学习 Linux 基础知识,并为参加基于 2009 年 4 月之前的早期 LPI 考试目标的系统管理员认证考试做准备。

  • 在 RPM 主页 上寻找关于 RPM 软件打包工具的最新信息和更多 RPM 信息的链接。

  • Maximum RPM 这本书全面系统地讨论了 RPM 的所有方面。可以获取它的硬拷贝和软拷贝。
  • 在 LSB Home 上了解 Linux Standard Base (LSB),这个 Free Standards Group (FSG) 项目致力于开发标准的二进制操作环境。

  • 访问 PackageKit 主页,了解关于 PackageKit 的更多信息。

  • Linux 文档项目 提供了大量有用的文档,特别是 HOWTO 文档。
  • 在 developerWorks Linux 专区 寻找为 Linux 开发人员(包括 Linux 新手入门)准备的更多参考资料,查阅我们 最受欢迎的文章和教程。
  • 在 developerWorks 上查阅所有 Linux 技巧 和 Linux 教程。
  • 随时关注 developerWorks 技术活动和网络广播。
  • 观看 developerWorks 演示中心,包括面向初学者的产品

    安装和设置演示,以及为经验丰富的开发人员提供的高级功能。

获得产品和技术

  • 在发行商的镜像站点上寻找包,比如 Fedora/12 Public Active Mirrors。

  • 在 Rpmfind.Net 和 RPM Search 上搜索适用于您的发行版的 RPM。

  • 以最适合您的方式 IBM 产品评估试用版软件:下载产品试用版,在线试用产品,在云环境下试用产品, 或者在 IBM SOA Sandbox for People 中花费几个小时来学习如何高效实现 Service

    Oriented Architecture。

讨论

  • 参与论坛讨论。
  • 加入 My developerWorks 社

    区。查看开发人员参与的博客、论坛、组和 wikis,并与其他 developerWorks 用户交流。

来源URL:http://www.ibm.com/developerworks/cn/linux/l-lpic1-v3-102-5/