Debian包管理系统
Debian包管理系统也许是类Unix系统上最为复杂的包管理系统。Debian的机制是网络透明的(也就是他可以通过网络透明的安装远程器上的软件包),而Debian也是第一个进行使用这样打包系统的发行版本。RH的up2date是最近的与Debian相似的软件功能,而Slackware Linux并没有达到真正的网络透明的程度。熟悉其他操作系统,如Windows,的用户也许会想到Windows的Update,然而Debian的机制会更为强大。这一部分将会详细的讨论Debian的包管理机制。
技术概要
Debian的包管理系统可以分为几层。最低层次是实际的包管理系统,而最高层次的是各种用来自动处理软件包定位,获得与软件包安装过程的用户友好的接口程序。下面的列表列出所要调用的主要程序:
PROGRAM BASED ON 用途
dpkg N/A 实际安装与管理软件包的程序
apt-get dpkg 管理软件包源列表和获取要安装的软件包
dselect apt-get,dpkg 允许用户从源列表文件中选择要安装的软件包
tasksel apt-get,dpkg 允许用户选择要安装的任务(本地软件包组)
下面的部分将会详细的讨论Debian的包管理程序。出于演示的目的,Debian的程序会与RH和Slackware中等价的程序进行对比。这仅仅是一个对比,我们的目的并不是要评判所一个系统是最优的。Debian系统是相当的复杂,而我们这样做只是为了方便我们的讨论。
使用dpkg程序
dpkg是Debian包管理系统的关键。这个程序负责实际的解包和安装Debian软件包归档文件(以deb为扩展名),并负责管理与软件包管理相关的各种数据库。
我们可以使用dpkg来手动的安装单个的软件包。例如,也许我们会从某个网站上下载一个deb文件并使用dpkg来进行安装,或者是我们要安装CD中的一个软件包。相似的,我们也可以使用 dpkg来移除某一个软件包。我们也可以使用dpkg来执行查询命令,例如列出某一个包所安装的文件或者是定位包含一个指定文件的软件包。
这时我们也许已经意识到dpkg程序本质上与rpm程序相类似,通过rpm程序,我们可以安装和移除软件包,或是在软件包执行各种查询命令(包括已安装和未安装的软件包)。Slackware会通过各种程序(installpkg,upgradepkg,removepkg)来完成相件的功能。
Slackware使用/var/log/package目录中的简单的文本文件来存储关于软件包与文件所属关系的各种信息。而RH却是另一个极端,他是将这样的各种信息存放在一个二进制数据库中,而我们只可以通过rpm命令来进行访问。Debian的dpkg是处于中间状态:一个软件包所安装的文件列表存放在一个数据库中,但是关于这个软件包的信息却是存放在/var/lib/dpkg/available文件中,而所以已经安装的软件包的信息存放在/var/lib/dpkg/info目录下。在某种程序上,我们可以为了某些信息而查看相关的文件,而这并不一定要通过使用dpkg工具来完成(虽然我们会发现dpkg工具会更为的方便)。
dpkg与rpm之间的一个主要区别在于dpkg维护一个事实上可用的(available)但是却还没有安装的软件包列表,也就是/var/lib/dpkg/available文件。(事实上,RH也提供了一个名为rpmdb的软件包来提供类似的功能,但是这个软件包却是相当的难用的)。这个列表是由CD或是其他的质上的内容组织而成的,并且这样的组织结构可以完成用各种的查询请求。(例如,用户也许会查询一个未安装的软件包的文档信息)。这是相当方便的,因为这意味着我们为了获得一个软件包的信息而并不需要这个deb软件包自身;而如果我们是使用rpm命令,我们就不得不实际的安装了这个软件包并且使用rpm -qp命令来进行相应的查询。
Debian的包管理系统与RH的RPM系统的另一个主要区别就在于他们的包依赖关系的解决。RPM可以跟踪依赖关系,也就是一个软件包所依赖的另一个软件包。例如,OpenSSH软件包依赖于OpenSSL软件包。如果使用RPM,依赖仅是一个yes或是no的建议。然而,dpkg工具可以支持几种类型的依赖,例如"required", "recommend", 和 "suggested"。这个额外的录活性可以使得软件包很容易的与终端用户交互依赖关系的信息。当我们要安装一个Debian的软件包时,记住一定要仔细检查软件包的依赖关系,因为我们会错过一些推荐或是建议的特征。
使用apt-get程序
apt-get程序建立在dpkg程序之上并且管理软件包源,提供前面提到的大多数的网络透明性。我们可以认为这个程序是为dpkg程序提供源的。dpkg所安装的软件包要从一个地方得到,而apt-get就是这个地方。apt-get的另一个主要责任就要跟踪软件包之间的依赖关系(如一个软件包需要另外的哪一个软件包)。
管理源介质
通常,用户会从安装CD或是网络上的一个安装仓库(如FTP站点)进行Debian的安装。这些安装介质构成了Debian软件包的集合,apt-get监视这些介质并且跟踪每一个源可用的软件包列表。当用户希望安装一个新的软件包时,他只是简单的执行apt-get来定位这个软件包并把他传递给dpkg进行安装。定位这个软件包也许意味着回到那个FTP站点,或者是提示用户插入一个安装CD,或是其他的事情。
践踏可用软件包的能力是一个主要的方便之处。如RPM的系统就是相当的近视的,rpm并不会看到没有直接坐到他面前的任何文件。相反,Debian的apt-get可更好的看到可用软件包的范围,并且可以获得软件包而不需要麻烦用户自己支下载。RH也有一个名为up2date的类似的系统,但是up2date仅仅知道由RH所维护的软件包仓库的信息。Debian的apt-get有一个更为灵活的软件包源列表。我们也可以将up2date看作是只可以处理一个软件包源的apt-get的兄弟。
apt-get所使用的源介质列表是由一些帮助程序来维护的。存储源列表的文件为/etc/apt/sources.list,这个文件要以包含各种源,例如CD,FTP或是HTTP站点等等。这个文件的内容可以很容易的由一些帮助程序来进行管理,例如apt-cdrom,这个程序可以搜索Debian软件包CD并且在/etc/apt/sources.list中创建合适的内容。
使用apt-get工作
当在一个Debian系统上维护软件包时,许多用户大部分时间使用apt-get。他最适合快速简单的安装那些我们在安装系统时并没有安装的软件包,或者是当软件包释出了修正或是加强时可以更新当前的软件包到一个更新的版本。然而事实上apt-get是相当的高级,他可以更新整个系统到一个新的版本。这些apt-get的特征会在以后进行更为详细的讨论。
使用dselect程序
dselect是一个基于菜单的接口从而可以选择我们要安装的软件包。事实上这个程序是在Debian的安装过程中调用的程序,从而可以以许用户修正软件包列表来满足他们的要求。这个程序也可以在调整所选择的列表的安装之后来运行。
这个程序仅是由apt-get和dpkg所维护的软件包列表内容的一个查看。也就是说,apt-get维护一个软件包源的列表,而dpkg维护一个可用的软件包列表(由源码编译的)。dselect程序简单的显示一个所有可用的软件包的列表,表明哪一个已经安装并且允许用户标记可用的软件包进行安装,或者是标记已安装的软件包进行删除。可用软件包的菜单也包含每一个软件包的依赖关系的信息,并且帮助用户选择软件包来解决依赖关系。
当用户做出了他的选择并退出dselect,apt-get(接下来为dpkg)就会运行依据用户的选择来进行实际的软件包的安装与删除。RH和Slackware并没有与dselect相类似的程序。
使用tasksel程序
tasksel程序与dselect相类似,但是并不是允许用户选择要安装的软件包,而是让用户选择任务。在Debian的术语中,一个任务本质上是一个软件包的集合。例如,X Window系统的XFree86实现事实上由许多不同的软件包所构成,包括核心软件,各种视频卡的驱动模块,以及字体文件。Debian有一个任务的概念可以允许发行版本的设计将软件包集合分组,例如将XFree86放入一个虚拟包中。当用户选择一个任务,实际上他选择一个包含多个Debian deb软件包的集合。
tasksel程序是相当直接的,而他本身使用apt-get,然后是dpkg来处理构成任务的软件包的安装。而对于dselect,RH以及Slackware并没有提供相类似的功能。
详细讨论
上面的几个部分我们概要的讨论了构成Debian包管理系统的各种程序所提供的功能。下面的几个部分将会讨论的更为深入一些,并且演示一些Debian包管理系统中常见的用法。然而,每一个程序都是相当复杂的,所以更为详细的讨论我们需要查看Debian GNU/Linux提供的手册以及其他的文档。
下面的几问分我们将会专注于演示作为一个整体使用Debian包管理系统最常用的方法,并不会专注于单个程序的机制。现在,我们已经很好的把握了类似于dpkg和rpm这样的工具在做什么(解包文件,将他们安装到哪里记入数据库以备以后删除,以及运行脚本)。为了避免重复我们会由手册页中得到的信息,我们将会专注于发行版本,而不仅仅是这些工具。
使用Debian系统维护软件包
即使我们可以通过阅读手册来了解如何使用他们,相比于我们从手册中立时得到的,Debian的包管理工具会提供更为强大和灵活的特性。下面的每一个部分将会专注于一个特定的常见的任务并且勾出那个任务的通常过程,依次来帮助我们从知道运行这些程序到知道何时运行他们的转变。这里很重要的一点就是我们要在心里记住,使用Debian包管理系统,任何事情都有不只一种解决的办法。通常可以在两个层次上管理包Debian软件包:在dpkg层次,以及在apt-get和dselect层次。这一部分将会讨论每一种情况,主要演示包管理的机制,并且展示何时以及为什么我们要使用每一层次。
使用dpkg工作
Debian的dpkg工具是包管理系统中最低层次的工具。他在单个软件包的层次上进行操作,并且可以执行经典的包命令,如install,remove以及各种查询。下面的列表列出了dpkg提供的最常见的操作。对于更为详细的内容,我们需要查阅手册页以及其他的文档。
命令 相应的RPM命令 功能
dpkg -i <filename> rpm -i <filename> 安装一个Debian软件包
dpkg -r <filename> rpm -e <filename> 删除一个已安装的软件包
dpkg -l rpm -qa 列出所有已安装的软件包
dpkg -l <package> rpm -q <package> 检查一个软件包是否已安装并打印出全名
dpkg -L <package> rpm -ql <package> 列出由一个软件包所安装的文件
dpkg -S <file> rpm -qf <file> 识别一个已安装的包含某个文件的软件包
dpkg -p <package> None 决定指定的软件是否可用于安装
有趣的通用表达式
通用表达式是指类似于星号(*)的通配符扩展来匹配特定的模式。Debian的dpkg程序,像大多数的包管理程序一样,支持所传递参数中的通用表达式。例如,要列出所有名字中带用”libc”的已安装的软件包,我们可以使用下面的命令:
$ dpkg -l "*libc"
这里的星号与Shell中文件名的通用表达式类似,所以这时我们就会得到一个名字中带有”libc”的软件包列表。这是相当方便的一件事。
使用apt-get管理软件包源
在我们的Debian系统上使用dpkg程序来管理软件包存在的唯一问题就是这是一件相当艰苦的工作。必竞,如果我们要安装一个指定的软件包,首先我们要找到这个软件包。这就会引发插入或是挂载CD,如果这个软件包并不在我们第一次所检查的CD上,我们就需要几次这样的操作。或者是从一个Web或是FTP站点下载这个软件包。即使我们所做的仅仅是安装一个我们在安装过程中忘记选择的一个软件包,我们也不得不使用CD或是URL来定位这个软件包。另外,我们也不得不也这个软件包所依赖的其他软件包进行斗争。
鉴于这些情况,Debian GNU/Linux包含了apt-get,这个工具会为我们管理安装介质。因为apt-get维护着一个包含软件包的介质源列表,与一个实际可用的软件包列表,我们所要做的就是请求apt-get定位并安装我们需要的软件包。下表列出了apt-get最常见的用法。我们可以查阅相关的手册而得到更为详细的信息。
命令 功能
apt-get install <package> 从可用的软件包列表中定位并安装指定的软件包
apt-get remove <package> 卸载指定的软件包与相关的依赖
apt-get update 刷新可用的软件包列表(在源列表更新以后)
apt-get upgrade 当有新版本可用时更新我们系统上所用的软件包
apt-get的前两个功能--安装与删除软件包--是相当直接的。只需要输入apt-get install foo,apt-get就会在他们的源列表与可用软件包列表中查找名为foo的Debian归档文件。如果找到了一个就会安装这个归档文件,同时会解决各种相关的依赖关系。相反的,apt-get remove foo会卸载这个软件包。然而剩下的两个功能并不是这样的明显。
更新已安装的软件包
在上面列出的apt-get的功能时有一点值得注意的就是更新并不是只作用在一个指定的软件包上。相反,他是一个全局的命令并且更新所有有可用更新的软件包。这最初看起来似乎有一些更严格的限制,因为这会使得更新单个软件包变得很困难。然而,如果我们仔细的想一下,一旦我们自动更新了系统本身,我们就不需要担心单个软件包,所以这在实际中并不是一个问题。
更新可用软件包列表
在上面的列表另一个并不明显的命令就是update命令。这个命令不同于我们刚才所描述的upgrade命令。update命令更新可用软件包列表,但是并不会实际的更新任何一个软件包。通常我们需要在更新了我们的/etc/apt/sources.list文件或是一个FTP或Web站点更新了他的可用软件包的列表时我们需要运行apt-get update。一旦apt-get明白存在对于已安装软件包的更新,upgrade命令就可以完成升级更新的工作。
使用dselect与tasksel管理软件包
有时,也许我们需要一次安装许多个软件包,或者是我们并不确定一个指定软件包的名字。有时我们甚至不知道满足一个特定需求的软件包是否存在。dselect与tasksel工具可以解决这样的情况。
使用dselect
dselect程序是最早出现在Debian GNU/Linux系统中的包管理程序,因为他是在安装过程中用来选择单个软件包的工具。dselect程序仅仅是一个基于菜单的前端程序,将我们直到现在所讨论的各种功能集中在一起。
管理员可以用dselect程序来浏览所有可用的软件包列表,而且可以立时看到安装了哪些软件包以及没有安装哪些软件包。通过改变选择列表,可以安装或是移除许多的软件包。对于这样的情况,dselect也许比使用apt-get来管理单个的软件包更为的方便。
使用tasksel
一个任务只是一个软件包列表。例如,XFree86任务包含许多单个的软件包,例如库,视频卡驱动以及字体。tasksel程序可以在安装结束以后用来安装额外的任务。
例如,也许一个系统最初是作为服务器来配置的,所以XFree86并没有安装。如果那个系统会重新作为一个桌面系统来使用,我们就不得不安装XFree86软件包。当然,这个可以通过使用apt-get手动来完成,但是会涉及到许多的软件包。所以也许简单一点的办法就是使用dselect来选择要安装的所有软件包,但是即使这样我们也不得不在软件包列表中搜索他们。然而,如果使用tasksel,整个的XFree86软件包整体,也就是XFree86任务,可以快速并简单的进行安装。
配置Debian软件包
包管理系统必须善于安装,升级以及卸载文件。大多数的也具有管理配置文件的功能,仅管他们支持的程度并不相同。例如,RH的RPM系统允许软件包的创建者设计一些文件作为配置文件。当后来管理这些文件时,RPM会非常小心的保存他们并且绝不会覆盖系统管理员自定义的文件。然后,Debian系统包含更多的配置支持。
Debian带有debconf软件包。这个软件包是库以及一些实用程序的集合,实现了一个软件包的设计者可以用来客理他们的软件包配置的协议。一个协议是一个控制程序员之间交流的标准,debconf协议允许软件包的创建者使用标准的方式向用户提出问题。debconf实用程序以及用户前端接口收集必须的软件包形为信息,并且将这些信息传递给软件包中所包含的安装脚本。这个脚本可以做任何必须的事情,如生成配置文件。
使用debconf软件包的例子就是X Window系统。XFree86需要大量的信息来配置X服务器以便与用户的硬件进行工作。RH为了他的安装编写了一个名为Xconfigurator的程序,但是Debian使用debconf工具。这两个程序之间有着极大的相似性,至少他们都是基于菜单的用户接口,他们会询问相似的问题并生成相似的文件。
使用debconf重新配置软件包
用户以及系统管理员常常需要在安装完成以后重新配置软件包。例如,一个工作站更新了一个新的视频卡,需要重新配置XFree86。鉴于这样的情况,debconf提供了两个工具:dpkg-preconfigure与dpkg-reconfigure。还有第三个工具:debconf-show,他会显示一个软件包的当前配置信息。
这两个配置命令,dpkg-preconfigure与dpkg-reconfigure,十分的相似。本质上来说,dpkg-preconfigure用来在软件包安装之前收集相应的信息,而且他在安装过程是最重要的。事实上大多数的用户并不会直接调用他。然而,dpkg-reconfigure完成相似的任务,但是可以配置已安装的程序。例如,命令dpkg-reconfigure xserver-common可以在重新了视频卡以后重新配置工作站。相似的,debconf-show xserver-common可以显示XFree86所用的配置变量以及他们的当前值。
配置debconf
debconf程序本身也有一些配置选项。主要的组件是/etc/apt/apt.conf.d目录以及/etc/debconf.conf文件。我们将会在下面分别讨论每一问分。然而,大多数用户并不需要经常处理这些文件。而我们只需要清楚他们的存在,也许有一天我们会用到他们。
/etc/apt/apt.conf.d目录是被apt包管理系统用来作为当apt工具被调用时运行程序的钩子。这个目录包含一些内容会被包管理工具在他们的操作中使用的文件。
/etc/debconf.conf 文件配置debconf系统本身。这个文件真正的指定了到存放配置信息的数据库文件的路径。debconf系统通过将软件包使用debconf与用户交互的问题答案记入一个独立于软件包内容的数据库来记住前一个问题的答案。如果一个软件包被移除了或是被重新安装(或者是简单的升级),debconf会从他的数据库中取出配置信息并使用这些值来重新运行配置脚本。要覆盖这个操作,我们可以使用dpkg-reconfigure程序。
更新系统
直到现在我们已经讨论了许多的工具提供各种方法来与Debian包管理系统工作。正如我们已经注意到的,一般来说这与其他的系统相似,仅管Debian的也许是一个更为丰富,更为高级的系统。然而,还有一个我们并没有涉及到的方便,而这就是Debian通过包管理系统进行更新升级的能力。
对于大多数的发行版本来说,升级更新是一个集中的过程。我们通常不得不从软盘或是CD启动,运行有特定目的的程序,从安装介质来更新我们的系统。然而,Debian系统是完全不同的方式进行处理。
这里的关键就是可用的软件包列表。大部分时间,我们也许会配置我们的系统使用相当稳定的源集合,但是但见偶然会包含一些Bug修正,安全修正等内容。在这样的情况下,我们可以通过类似于下面的方法来用新的软件包更新我们的安装:
1 如果必须,可以更新/etc/apt/sources.list来反应新的介质。例如,我们也许得到了一个包含更新软件包的CD,并且需要使用apt-cdrom命令来添加这个新的CD。
2 运行apt-get update命令以使得apt-get清楚已更新的软件包。
3 运行apt-get upgrade命令以使得apt-get获得并安装可用的更新软件包。
当我们需要做的只是更新一些软件包时,这样的过程可以工作得很好。然而,事实上我们也许希望将我们的Debian系统更新到一个新的版本。当我们希望这样做时,这样的情况与我们前面讨论的也并没有太大的不同。我们仅是需要用新的版本的软件包来替换当前已经安装的软件包。所不同的仅是更新的范围:在一个主版本的更新中,大量(也许是全部)的软件包进行连续的改变,通常是每一个软件包内容的主要改变。
管理那样的完全的更新着并是很简单的,所有大多数的发行版本只是制作新的CD,而我们要重新启动系统来进行更新。然而,对于Debian系统,我们可以用下面的过程来完成:
1 更新etc/apt/sources.list,移除所有到当前发行版本介质的引用,并添加新的主版本的实体内容。(例如,更新一个网络安装的URL或是添加一个新的本地安装的新的CD)
2 运行apt-get update更新可用的软件包列表以及版本
3 运行apt-get dist-upgrade来着际更新发行版本。这个命令会使得apt-get进入另一个合适的安装模式来片是在整个系统更新中会出现的各种复杂的依赖关系。
4 当更新完毕,重新启动系统来完成安装过程。
我们可以很明显的看到一个整个发行版本的更新过程类似于前面的处理一个特定版本的小的更新。当然系统也需要重启(例如,如果我们更新的内核),然而,这却是一个优雅的过程。
操作Debian软件包归档
我们已经读到的所有软件包一定是来自某个地方,所以很自然的我们就会问到这些软件包是怎么样创建的。也许有一天我们希望或是需要查看一个Debian软件包中的内容,或是从中解压出某一个特定的文件,或是在一个非常基础的层次上进行处理。为了支持这些任务,Debian中包含有一个名为dpkg-deb的程序来管理单个的Debian软件包。下表列出了dpkg-deb程序的用法。我们可以查阅相关的手册页得到更为详细的内容。
命令 相似的RPM命令 功能
dpkg-deb -build rpm -ba 创建一个新的软件包
dpkg-deb -info <filename> rpm -qpi 从软件包中解压出通用信息
dpkg-deb -contents <filename> rpm -qpl 显示一个软件包的内容
正如上表所显示,dpkg-deb的功能或多或少的与RPM的功能相似。然而,在实际创建一个归档文件时的操作却是本质上的不同。本质上,RPM软件包是由在.spec文件中所包含的特定脚本来创建的,这些文件包含有由一个源码包创建一个二进制的RPM包时所需要的全部信息。
相对的,Debian的软件包是由dpkg-deb -build命令来组织的,这个命令通过收集当前目录下的内容并且处理DEBIAN目录下名字控制名字来创建软件包。事实上,Debian创建软件包的方法更类似于Slackware,而不是RH。
管理源码
一些读者也会希望知道Debian是否支持源码软件包,就如同RH的RPM支持.src.rpm文件的方法。答案是肯定的。因为Debian的软件包是被创建用来简单归档特定目录下的内容,创建一个包含源码的deb是一件很简单的事情。然而,并没有通常所谓的Debian源码软件包的概念,Debian软件包的源码是作为标准的tar包的形式进行分发的,在这个tar包中包含有源码以及要为Debian GNU/Linux构建软件包所必须的补丁。
安装非Debian的软件包
正如我们在前面所提到的,也许我们找到的某个特定程序的软件包是RPM打包的格式而不是Debian软件包格式。所以Debian的用户常常会处于一种令人讨厌的情况下,然而他们希望安装一个二进制的软件包,而这个软件包是用非Debian的格式进行分发的。
为了解决这样的问题,Debian GNU/Linux包含一个相异的程序。这是一个可以在不同的打包格式之间进行相互转换的工具。例如,他允许Debian的用户将一个RPM文件转换成为一个Debian的deb文件。然后用户就可以在他们的Debian系统上安装这个软件包(当然这里假定他满足软件包之间的依赖关系)。然而,因为每一个软件包的格式都有一个他自忆的规则,这就会导致有一些软件包不能被正确的处理。这并不是一个完美的解决办法,但是这确实很有帮助。
机制与用户接口
正如我们到现在已经注意到的,Debian的软件包管理系统本质上不同于RH或是Slackware。然而RH或是Slackware都或多或少的自动处理了软件包实际安装过程,但是Debian系统却将他带入了另一个层次。
演示的最好方法是就是对比Debian GNU/Linux与RH的安装过程。在RH的安装过程中,用户从一个安装类的集合中选择,例如,服务器,工作站,或是桌面。这些选项是为所选择的安装类别而自定义的一个安装软件包列表的模板。用户可以在安装以后进行修改,但是那时却是从CD或是网络上定位或是取得某一个软件包并且手动的进行安装。
Debian GNU/Linux采用相似的方法,但是去并不完全相同。Debian的安装程序只是安装了一个最简单的软件包集合,仅仅是可以启动系统。然后会提示用户使用dselect程序从一个单独的可用的软件包列表来构建一个要安装的软件包列表。在任何时候,都只是在系统上安装可用软件包列表的一个子集。这个方法也使得当有Bug修正时更新系统更为的容易,或者是更新到一个新的版本,这个过程都是很自然的。
当然,所有这些灵活性也是要付出一定的代价的,也就是复杂。一些在享受apt-get以及他所提供的便利,而另一些人却认为RPM是最好的打包格式。当然其他的人,遵从KISS(Keep It Simple,Stupid)的哲学思想而喜欢Slackware的机制。对于每一个系统都有自已不同的倡导者,虽然他们有许多相互重叠的功能。当然,最后,每一个用户都会选择他们认为最好的来用。