APT HOWTO
第三章 软件包管理
3.1 更新可用软件包列表
======================
软件包管理系统使用一个私有数据库跟踪列表中软件包的当前状态:已安装、未安装或可安装。apt-get通过该数据库来确定如何安装用户想用的软件包以及正常运行软件包所必须的其它关联包。
你可以使用apt-get update来更新数据库列表。这个命令将扫描/etc/apt/sources.list文件中所指路径中的软件包列表文件。有关该列表文件的更多信息请查阅 第二章 /etc/apt/source.list文件。
定时运行这个程序是个好主意,它将使你和你的系统获得最新的软件包更新和安全更新等信息。
3.2 安装软件包
==============
现在,终于到了你一直期待的阶段!准备好了sources.list和最新版的的可用软件包,你所需做的就是运行apt-get来安装你渴望已久的软件了。例如,你可以这样:
apt-get install xchat
APT会扫描它的数据库找到最新的版本的软件包,并将它从sources.list中所指的地方下载到本地。如果该软件包需要其它软件包才能正常运行——如本例一样——APT会做关联性检查并自动安装所关联软件包。如下所示:
[root]@[/] # apt-get install nautilus
Reading Package Lists... Done
Building Dependency Tree... Done
The following extra packages will be installed:
bonobo libmedusa0 libnautilus0
The following NEW packages will be installed:
bonobo libmedusa0 libnautilus0 nautilus
0 packages upgraded, 4 newly installed, 0 to remove and 1 not upgraded.
Need to get 8329kB of archives. After unpacking 17.2MB will be used.
Do you want to continue? [Y/n]
nautilus软件包需要引用共享函数库,因此APT会从镜像源处下载相关共享函数库,如果你在apt-get命令行中手动指定了这些共享函数库的名称,APT会默认为你要安装所有这些软件包。
也就是说APT只会在安装那些没有在命令行中指定的软件包时提示你进行确认。
下列apt-get选项也许对你有用
-h This help text.
-d Download only - do NOT install or unpack archives
-f Attempt to continue if the integrity check fails
-s No-act. Perform ordering simulation
-y Assume Yes to all queries and do not prompt
-u Show a list of upgraded packages as well
可以用一条命令安装多个软件包。包文件从网络上下载到本地/var/cache/apt/archives目录,稍后再安装。
你可以用同样的命令行删除指定软件包,只需在软件包名称后紧跟一个“-”,如下所示:
[root]@[/] # apt-get install nautilus gnome-panel-
Reading Package Lists... Done
Building Dependency Tree... Done
The following extra packages will be installed:
bonobo libmedusa0 libnautilus0
The following packages will be REMOVED:
gnome-applets gnome-panel gnome-panel-data gnome-session
The following NEW packages will be installed:
bonobo libmedusa0 libnautilus0 nautilus
0 packages upgraded, 4 newly installed, 4 to remove and 1 not upgraded.
Need to get 8329kB of archives. After unpacking 2594kB will be used.
Do you want to continue? [Y/n]
有关删除软件包的更多详细信息,参阅 3.3 移除软件包。
假如你不小心损坏了已安装的软件包而想修复它,或者仅仅想安装软件包中某些文件的最新版本,这是可以做到的,你可以用--reinstall选项:
[root]@[/] # apt-get --reinstall install gdm
Reading Package Lists... Done
Building Dependency Tree... Done
0 packages upgraded, 0 newly installed, 1 reinstalled, 0 to remove and 1 not upgraded.
Need to get 0B/182kB of archives. After unpacking 0B will be used.
Do you want to continue? [Y/n]
本文档写作时所参考的APT版本为0.5.3,这个版本还属于“unstable”(sid)阶段。如是你安装了这个版本,你可以在系统配置中使用新增的功能:你可以用apt-get install package/distribution来安装指定发布版中的软件包,或者用apt-get install package=version,如下所示:
apt-get install nautilus/unstable
它将为你安装“unstable”发布版中的nautilus软件包,即使你当前运行的是“stable”版本。命令中“distribution”选项的可用参数值为:stable,testing,unstable。
在处理关联问题时,你可能更乐意使用-t开关来选择目标发布版,让apt-get帮你考虑使用哪个发布版。
重要信息:最新版的Debian软件包首先会上传到“unstable”发布版中,这个发布版包含了软件包所有更改阶段,无论是小修小补还是影响到众多软件包乃至整个系统的重大修改。所以,新手和那些强调系统稳定性的用户不会使用这个发布版。
“testing”发布版比起“unstable”发布版,多注重了些系统稳定性,但正式运行的系统应当使用“stable”发布版。
3.3 移除软件包
==============
如果你不再使用某些软件包,你可以用APT将其从系统中删除。要删除软件包只需输入:apt-get remove package。如下所示:
[root]@[/] # apt-get remove gnome-panel
Reading Package Lists... Done
Building Dependency Tree... Done
The following packages will be REMOVED:
gnome-applets gnome-panel gnome-panel-data gnome-session
0 packages upgraded, 0 newly installed, 4 to remove and 1 not upgraded.
Need to get 0B of archives. After unpacking 14.6MB will be freed.
Do you want to continue? [Y/n]
由上例可知,APT会关注那些与被删除的软件包有依赖关系的软件包。使用APT删除一个软件包将会连带删除那些与该软件包有依赖关系的软件包。
上例中运行apt-get会删除指定软件包以及与之有依赖关系的软件包,但它们的配置文件,如果有的话,会完好无损地保留在系统里。如果想彻底删除这些包及其配置文件,运行:
[root]@[/] # apt-get --purge remove gnome-panel
Reading Package Lists... Done
Building Dependency Tree... Done
The following packages will be REMOVED:
gnome-applets* gnome-panel* gnome-panel-data* gnome-session*
0 packages upgraded, 0 newly installed, 4 to remove and 1 not upgraded.
Need to get 0B of archives. After unpacking 14.6MB will be freed.
Do you want to continue? [Y/n]
注意:软件包名字后面的*表示该软件包所有的配置文件也将被删除。
就象安装软件时一样,你可以在删除命令中用一个符号来指定安装某个软件包。在删除软件包时,如果你在软件包名字后面紧跟一个“+”,那么该软件包就会被安装而不是删除。
[root]@[/] # apt-get --purge remove gnome-panel nautilus+
Reading Package Lists... Done
Building Dependency Tree... Done
The following extra packages will be installed:
bonobo libmedusa0 libnautilus0 nautilus
The following packages will be REMOVED:
gnome-applets* gnome-panel* gnome-panel-data* gnome-session*
The following NEW packages will be installed:
bonobo libmedusa0 libnautilus0 nautilus
0 packages upgraded, 4 newly installed, 4 to remove and 1 not upgraded.
Need to get 8329kB of archives. After unpacking 2594kB will be used.
Do you want to continue? [Y/n]
注意,apt-get列出了那些将要被安装的关联软件包(即保证该软件包正常运行的其它软件包)和将要被删除关联软件包,然后,再次列出了将要被安装的软件包。
3.4 更新软件包
==============
软件包更新是APT最成功的特点。只需一条命令即可完成更新:apt-get upgrade。你可以使用这条命令从相同版本号的发布版中更新软件包,也可以从新版本号的发布版中更新软件包,尽管实现后一种更新的首选命令为apt- get dist-upgrade;实情参阅 3.5升级到新版本。
在运行该命令时加上-u选项很有用。这个选项让APT显示完整的可更新软件包列表。不加这个选项,你就只能盲目地更新。APT会下载每个软件包的最新更新版本,然后以合理的次序安装它们。注意在运行该命令前应先运行apt-get update更新数据库。有关详情参阅 3.1更新可用软件包列表。看看这个例子:
[root]@[/] # apt-get -u upgrade
Reading Package Lists... Done
Building Dependency Tree... Done
The following packages have been kept back
cpp gcc lilo
The following packages will be upgraded
adduser ae apt autoconf debhelper dpkg-dev esound esound-common ftp indent
ipchains isapnptools libaudiofile-dev libaudiofile0 libesd0 libesd0-dev
libgtk1.2 libgtk1.2-dev liblockfile1 libnewt0 liborbit-dev liborbit0
libstdc++2.10-glibc2.2 libtiff3g libtiff3g-dev modconf orbit procps psmisc
29 packages upgraded, 0 newly installed, 0 to remove and 3 not upgraded.
Need to get 5055B/5055kB of archives. After unpacking 1161kB will be used.
Do you want to continue? [Y/n]
整个更新过程非常简单。注意在本例中头几行,apt-get报告有些软件包的更新被阻止(kept back),这表明这些软件包的更新版本因故无法安装,可能的原因有关联不同步(当前没有供下载的新版本关联包)或关联扩展(需要安装新的关联包以配合新版软件包)。
对于第一种原因没有很好的解决方法,对于第二次原因,运行apt-get intall安装所需的新关联包就可以。另一个更好的解决方法就是使用dist-upgrade。详情参阅 3.5升级到新版本。
3.5 升级到新版本
================
APT的绝活就是让你一次就完成整个系统的更新,不论是通过Internet还是通过光盘文件(购买的碟片或下载的ISO镜像文件)。
它也可以用来更新寻些改变了关联关系的软件包。即如前所述的那些使用apt-get upgrade时被阻止更新(kept back)的软件包。
例如,假设你目前使用的Debian为stable revision 0(如woody 3.0 r0,译者注),而你购买了revision 3的新版Debian(如woody 3.0 r3,译者注),你可以使用APT从新光盘上升级你的系统。使用apt-cdrom(参阅 2.4将CD-ROM加入source.list文件)将光盘加载到/etc/apt/sources.list中,然后运行apt-get dist-upgrade。
请注意,APT总是搜索最新版本的软件包,因此,如果一个软件包在你的/etc/apt/sources.list中所列的版本比光盘上所列的版本要新,那么APT会按照sources.list文件所指的地址下载这个软件包而不是使用光盘上的软件包。
在 3.4更新软件包 中我们举了个例子,我们看到有些包被阻止更新(kept back),现在我们就用dist-upgrade方法来解决这个问题:
[root]@[/] # apt-get -u dist-upgrade
Reading Package Lists... Done
Building Dependency Tree... Done
Calculating Upgrade... Done
The following NEW packages will be installed:
cpp-2.95 cron exim gcc-2.95 libident libopenldap-runtime libopenldap1
libpcre2 logrotate mailx
The following packages have been kept back
lilo
The following packages will be upgraded
adduser ae apt autoconf cpp debhelper dpkg-dev esound esound-common ftp gcc
indent ipchains isapnptools libaudiofile-dev libaudiofile0 libesd0
libesd0-dev libgtk1.2 libgtk1.2-dev liblockfile1 libnewt0 liborbit-dev
liborbit0 libstdc++2.10-glibc2.2 libtiff3g libtiff3g-dev modconf orbit
procps psmisc
31 packages upgraded, 10 newly installed, 0 to remove and 1 not upgraded.
Need to get 0B/7098kB of archives. After unpacking 3118kB will be used.
Do you want to continue? [Y/n]
注意现在那些软件包将会被更新,那些新的关联软件包也会被安装。但是lilo仍被阻止更新,可能还存在一些比建立新关联更棘手的问题,我们通过如下方法确定问题所在:
[root]@[/] # apt-get -u install lilo
Reading Package Lists... Done
Building Dependency Tree... Done
The following extra packages will be installed:
cron debconf exim libident libopenldap-runtime libopenldap1 libpcre2
logrotate mailx
The following packages will be REMOVED:
debconf-tiny
The following NEW packages will be installed:
cron debconf exim libident libopenldap-runtime libopenldap1 libpcre2
logrotate mailx
The following packages will be upgraded
lilo
1 packages upgraded, 9 newly installed, 1 to remove and 31 not upgraded.
Need to get 225kB/1179kB of archives. After unpacking 2659kB will be used.
Do you want to continue? [Y/n]
查看上述提示信息可知,lilo与debconf-tiny包产生了一个新冲突,这表明除非删除debconf-tiny,否则将无法更新lilo。
想知道该保留或删除哪些软件包,你可以使用:
# apt-get -o Debug::pkgProblemResolver=yes dist-upgrade
Reading Package Lists... Done
Building Dependency Tree... Done
Calculating Upgrade... Starting
Starting 2
Investigating python1.5
Package python1.5 has broken dep on python1.5-base
Considering python1.5-base 0 as a solution to python1.5 0
Holding Back python1.5 rather than change python1.5-base
Investigating python1.5-dev
Package python1.5-dev has broken dep on python1.5
Considering python1.5 0 as a solution to python1.5-dev 0
Holding Back python1.5-dev rather than change python1.5
Try to Re-Instate python1.5-dev
Done
Done
The following packages have been kept back
gs python1.5-dev
0 packages upgraded, 0 newly installed, 0 to remove and 2 not upgraded.
现在,你很容易就知道不能安装python1.5-dev软件包是因为无法满足另一个软件包python1.5的关联要求。
3.6 移除无用软件包文件:apt-get clean and autoclean
===================================================
当你需要安装某个软件包时,APT从/etc/apt/sources.list中所列的主机下载所需的文件,将它们保存到本机软件库(/var/cache/apt/archives/),然后开始安装,参阅 3.2 安装软件包。
本地软件库会不断膨胀占用大量硬盘空间,幸运的是,APT提供了工具来管理本地软件库:apt-get的clean方法和autoclean方法。
apt-get clean将删除/var/cache/apt/archives目录和/var/cache/apt/archives/partial目录下的所有文件,除了被锁定的文件。这样以来,当你需要再次安装某个软件包时,APT将重新下载它。
apt-get autoclean仅删除那些不需要再次下载的文件。
下面这个例子显示了apt-get autoclean如何工作:
# ls /var/cache/apt/archives/logrotate* /var/cache/apt/archives/gpm*
logrotate_3.5.9-7_i386.deb
logrotate_3.5.9-8_i386.deb
gpm_1.19.6-11_i386.deb
在/var/cache/apt/archives目录下有两个不同版本的logrotate软件包文件以及一个gpm软件包文件。
# apt-show-versions -p logrotate
logrotate/stable uptodate 3.5.9-8
# apt-show-versions -p gpm
gpm/stable upgradeable from 1.19.6-11 to 1.19.6-12
apt-show-versions显示logrotate_3.5.9-8_i386.deb提供了logrotate的升级版本,所以 logrotate_3.5.9-7_i386.deb没用了。同样gpm_1.19.6-11_i386.deb也没有用了,因为可以下载该软件包的更新版本。
# apt-get autoclean
Reading Package Lists... Done
Building Dependency Tree... Done
Del gpm 1.19.6-11 [145kB]
Del logrotate 3.5.9-7 [26.5kB]
总之,apt-get autoclean仅删除那些过时的文件。参阅 3.9如何从Debian的专用版本下升级软件包 获得更多apt-show-versions相关信息。
3.7 在dselect中操作APT
======================
dselect工具帮助用户选取想要安装的Debian软件包。它有点复杂甚至令人望而生厌,但经过实践你就能掌握它恐怖的终端界面。
dselect高级功能之一就是它知道利用Debian软件包的“推荐”和“建议”能力。(Debian软件包有一种能力:推荐或建议系统在安装自己的同时,安装别的软件包以配合自身的工作,当然这些推荐的软件包不一定是必须的;而dselect工具可以识别和利用这个能力,使用dselect时你就能体会到。译者注)以root身份运行dselect,进入程序后选择apt作为连接方式(access)。该步骤不是必须的,但如果你没有光驱而且想通过 Internet下载安装软件包,这是使用dselect的最好方法。
想深入学习dselect的用法,请到Debian网站查阅dselect文档页面
在dselect中选好了软件包后,运行:
apt-get -u dselect-upgrade
如下例所示:
[root]@[/] # apt-get -u dselect-upgrade
Reading Package Lists... Done
Building Dependency Tree... Done
The following packages will be REMOVED:
lbxproxy
The following NEW packages will be installed:
bonobo console-tools-libs cpp-3.0 enscript expat fingerd gcc-3.0
gcc-3.0-base icepref klogd libdigest-md5-perl libfnlib0 libft-perl
libgc5-dev libgcc300 libhtml-clean-perl libltdl0-dev libsasl-modules
libstdc++3.0 metamail nethack proftpd-doc psfontmgr python-newt talk tidy
util-linux-locales vacation xbill xplanet-images
The following packages will be upgraded
debian-policy
1 packages upgraded, 30 newly installed, 1 to remove and 0 not upgraded.
Need to get 7140kB of archives. After unpacking 16.3MB will be used.
Do you want to continue? [Y/n]
比较一下我们在相同系统上运行apt-get dist-upgrade时的情形:
[root]@[/] # apt-get -u dist-upgrade
Reading Package Lists... Done
Building Dependency Tree... Done
Calculating Upgrade... Done
The following packages will be upgraded
debian-policy
1 packages upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Need to get 421kB of archives. After unpacking 25.6kB will be freed.
Do you want to continue? [Y/n]
我们看到在前例中许多软件包被安装是其它软件包“推荐”或“建议”的结果。另外一些软件包被安装或删除(例如lbxproxy软件包)是我们通过dselect工具作出的决定。由此可见dselect与APT结合起来将是一个功能强大的工具。
3.8 如何构建一个混合系统
========================
人们常使用testing发布版,因为它比unstable要稳定同时又比stable时髦。然而对于那些想运行某些软件包的最新版本,又不希望将整个系统迁移到unstable发布版的还有一种选择:运行一个testing/unstable混合系统。对另一部分保守的用户而言,他们可能希望运行 stable/testing混合系统。
要实现混合系统,请在/etc/apt/apt.conf中加入下面的语句:
APT::Default-Release "testing";
以后,在从unstable发布版安装软件包时,使用-t开关:
# apt-get -t unstable install packagename
别忘了,使用Debian的某个发布版的软件包时,要将镜像源加入到/etc/apt/sources.list文件中。在这个例子中,除了加入testing发布版镜像源处,我们还需要加入unstable发布版镜像源。
3.9 如何从Debian的专用版本下升级软件包
======================================
apt-show-versions提供了一个安全的途径,让那些使用混合系统的用户放心升级他们的系统,不必担心升级会将原来属于stable的包升级成了unstable包。例如,这条命令将只升级你的unstable软件包:
# apt-get install `apt-show-versions -u -b | grep unstable`
3.10 如何维护已安装软件包的多个版本(复杂)
==========================================
你可能会遇到这种情况,更改了某个软件包中的一些文件,但你没有时间或根本就不想将这些更改引入到新版本中。或者,你将系统升级到3.0,但仍想继续使用Debian 2.2下的某个软件包。你可以“钉住”(pin)这个版本,这样它就不会被更新了。
操作起来十分简单,你只需编辑/etc/apt/preferences文件。
文件格式很简单:
Package: <package>
Pin: <pin definition>
Priority: <pin's priority>
例如,我对sylpheed软件包做了某些修改,其版本为0.4.99,我想保留这些修改不被更新,可加上:
Package: sylpheed
Pin: version 0.4.99*
注意我用了一个 *(星号)。这是一个“通配符”;它表明我希望“钉住”所有以0.4.99打头的版本(以防它们被下载并安装到我机器上。pin控制的是服务器端的更新软件包而非本地的已安装软件包。译者注)。因为Debian使用“Debian版本号”为其软件包定版本,我不想进行所有这些版本的升级,如果不用通配符,那么0.4.99-1版或0.4.99-10版只要一出炉系统就会安装它们。如果你修改了软件包,你一定不希望这么做。
Priority是可选域;如果没有特别指定,它的默认值为989。
让我们来看看pin如何体现优先级(priorty)区别。一个低于0的优先级表示:该软件包被禁止安装;优先级在0到100之间表示:软件包没有安装并且当前也没有可用版本,这些软件包不会出现在供选择版本列表中;优先级为100表示软件包已被安装——对于这个已安装的软件包,如果有一个不同的版本要替换它,那么替换者的优先级必须大于100。
优先级在100以上表示软件包应该被安装。典型的例子如,某个软件包的升级补丁包,任何处于100和1000(包括1000)之间的优先级都表示上述情形。但是,一个软件包如果被定为这样的优先级,它并不会降级已安装的版本。例如,如果我安装了sylpheed 0.5.3并为sylpheed 0.4.99指定了一个优先级为999的pin,那么由于要满足pin的优先级,所以0.4.99软件包不会被安装。如果要实现软件包“降级”,则需要将 pin的优先级定为大于1000。(100<优先级<=1000时,如果存在升级包就对本机相关包升级,如果本机软件包比更新包还新就保持不变;优先级>1000时,服务器端软件包不论比本机的软件包新还是旧,均对本机相关软件包进行更新。译者注)
pin可以被用来控制软件包的修订版本(version)、发布版本(release)或版本来源(origin)。
在前面我们已经看到,钉住修订版本时使用通配符来代替版本号数字,这样可一次指定多个版本。
release选项是基于发布版文件(Release file)的,这个文件在本地APT软件库中或安装光盘上。如果你从本地软件库安装软件包而软件库中又没有该文件,那么这个选项将失效。来看看 /var/lib/apt/lists/目录中发布版文件的内容,发布版包括这些参数:a(archive),c(components),v (version),o(origin),l(lable)。
来看一个例子:
Package: *
Pin: release v=2.2*,a=stable,c=main,o=Debian,l=Debian
Priority: 1001
在本例中,我们选择了version为2.2*的Debian(它可以是2.2r2,2.2r3——这些版本包含了“point releases”即安全更新和其它非常生要的更新),stable软件库,main类软件包(非contrib或non-free),版本来源和标签均为Debian。版本来源(o=)说明谁制作了这个发布版文件,标签(l=)说明该发布版的名称:Debian即是指Debian自己,Progeny即是指后裔制作者,下面是一个发布版文件的样例:
$ cat /var/lib/apt/lists/ftp.debian.org.br_debian_dists_potato_main_binary-i386_Release
Archive: stable
Version: 2.2r3
Component: main
Origin: Debian
Label: Debian
Architecture: i386