Linux【8】-软件管理-2-1-软件包简介

在前一章我们提到以原始码的方式来安装软体,也就是利用厂商释出的Tarball 来进行软体的安装。不过,你应该很容易发现,那就是每次安装软体都需要侦测作业系统与环境、设定编译参数、实际的编译、 最后还要依据个人喜好的方式来安装软体到定位。这过程是真的很麻烦的,而且对于不熟整个系统的朋友来说,还真是累人啊!

那有没有想过,如果我的Linux系统与厂商的系统一模一样,那么在厂商的系统上面编译出来的执行档,自然也就可以在我的系统上面跑啰!也就是说,厂商先在他们的系统上面编译好了我们使用者所需要的软体,然后将这个编译好的可执行的软体直接释出给使用者来安装,如此一来,由于我们本来就使用厂商的Linux distribution ,所以当然系统(硬体与作业系统)是一样的,那么使用厂商提供的编译过的可执行档就没有问题啦!说的比较白话一些,那就是利用类似Windows的安装方式,由程式开发者直接在已知的系统上面编译好,再将该程式直接给使用者来安装,如此而已。

那么如果在安装的时候还可以加上一些与这些程式相关的资讯,将他建立成为资料库,那不就可以进行安装、反安装、 升级与验证等等的相关功能啰(类似Windows 底下的『新增移除程式』)?确实如此,在Linux 上面至少就有两种常见的这方面的软体管理员,分别是RPM 与Debian 的dpkg 。我们的CentOS 主要是以RPM 为主,但也不能不知道dpkg 啦!所以底下就来约略介绍一下这两个玩意儿。

一、Linux 界的两大主流: RPM 与DPKG

由于自由软体的蓬勃发展,加上大型Unix-Like 主机的强大效能,让很多软体开发者将他们的软体使用Tarball 来释出。后来Linux 发展起来后,由一些企业或社群将这些软体收集起来制作成为distributions 以发布这好用的Linux 作业系统。但后来发现到,这些distribution 的软体管理实在伤脑筋, 如果软体有漏洞时,又该如何修补呢?使用tarball 的方式来管理吗?又常常不晓得到底我们安装过了哪些程式?因此,一些社群与企业就开始思考Linux 的软体管理方式。

如同刚刚谈过的方式,Linux开发商先在固定的硬体平台与作业系统平台上面将需要安装或升级的软体编译好,然后将这个软体的所有相关档案打包成为一个特殊格式的档案,在这个软体档案内还包含了预先侦测系统与相依软体的脚本,并提供记载该软体提供的所有档案资讯等。最终将这个软体档案释出。用户端取得这个档案后,只要透过特定的指令来安装,那么该软体档案就会依照内部的脚本来侦测相依的前驱软体是否存在,若安装的环境符合需求,那就会开始安装,安装完成后还会将该软体的资讯写入软体管理机制中,以达成未来可以进行升级、移除等动作呢。

目前在Linux 界软体安装方式最常见的有两种,分别是:

dpkg:

这个机制最早是由Debian Linux社群所开发出来的,透过dpkg的机制, Debian提供的软体就能够简单的安装起来,同时还能提供安装后的软体资讯,实在非常不错。只要是衍生于Debian的其他Linux distributions大多使用dpkg这个机制来管理软体的,包括B2D, Ubuntu等等。

RPM:

这个机制最早是由Red Hat这家公司开发出来的,后来实在很好用,因此很多distributions就使用这个机制来作为软体安装的管理方式。包括Fedora, CentOS, SuSE等等知名的开发商都是用这咚咚。

如前所述,不论dpkg/rpm 这些机制或多或少都会有软体属性相依的问题,那该如何解决呢?其实前面不是谈到过每个软体档案都有提供相依属性的检查吗?那么如果我们将相依属性的资料做成列表, 等到实际软体安装时,若发生有相依属性的软体状况时,例如安装A 需要先安装B 与C ,而安装B 则需要安装D 与E 时,那么当你要安装A ,透过相依属性列表,管理机制自动去取得B, C, D, E 来同时安装, 不就解决了属性相依的问题吗?

没错!您真聪明!目前新的Linux 开发商都有提供这样的『线上升级』机制,透过这个机制, 原版光碟就只有第一次安装时需要用到而已,其他时候只要有网路,你就能够取得原本开发商所提供的任何软体了呢!在dpkg 管理机制上就开发出APT 的线上升级机制,RPM 则依开发商的不同,有Red Hat 系统的yum , SuSE 系统的Yast Online Update (YOU) 等。

我们这里使用的是CentOS系统嘛!所以说:使用的软体管理机制为RPM机制,而用来作为线上升级的方式则为yum!底下就让我们来谈谈RPM与YUM的相关说明吧!

二、 什么是RPM 与SRPM

RPM全名是『RedHat Package Manager』简称则为RPM啦!顾名思义,当初这个软体管理的机制是由Red Hat这家公司发展出来的。RPM是以一种资料库记录的方式来将你所需要的软体安装到你的Linux系统的一套管理机制。

他最大的特点就是将你要安装的软体先编译过, 并且打包成为RPM 机制的包装档案,透过包装好的软体里头预设的资料库记录, 记录这个软体要安装的时候必须具备的相依属性软体,当安装在你的Linux 主机时, RPM 会先依照软体里头的资料查询Linux 主机的相依属性软体是否满足, 若满足则予以安装,若不满足则不予安装。那么安装的时候就将该软体的资讯整个写入 RPM 的资料库中,以便未来的查询、验证与反安装!这样一来的优点是:

  1. 由于已经编译完成并且打包完毕,所以软体传输与安装上很方便(不需要再重新编译);
  2. 由于软体的资讯都已经记录在Linux 主机的资料库上,很方便查询、升级与反安装

但是这也造成些许的困扰。由于RPM档案是已经包装好的资料,也就是说,里面的资料已经都『编译完成』了!所以,该软体档案几乎只能安装在原本预设的硬体与作业系统版本中。 也就是说,你的主机系统环境必须要与当初建立这个软体档案的主机环境相同才行!举例来说,rp-pppoe这个ADSL拨接软体,他必须要在ppp这个软体存在的环境下才能进行安装!如果你的主机并没有ppp这个软体,那么很抱歉,除非你先安装ppp否则rp-pppoe就是不让你安装的(当然你可以强制安装,但是通常都会有点问题发生就是了!)。

所以,通常不同的distribution所释出的RPM档案,并不能用在其他的distributions上。举例来说,Red Hat释出的RPM档案,通常无法直接在SuSE上面进行安装的。更有什者,相同distribution的不同版本之间也无法互通,例如CentOS 6.x的RPM档案就无法直接套用在CentOS 7.x !因此,这样可以发现这些软体管理机制的问题是:

  1. 软体档案安装的环境必须与打包时的环境需求一致或相当;
  2. 需要满足软体的相依属性需求;
  3. 反安装时需要特别小心,最底层的软体不可先移除,否则可能造成整个系统的问题!

那怎么办?如果我真的想要安装其他distributions提供的好用的RPM软体档案时?呵呵!还好,还有SRPM这个东西!SRPM是什么呢?顾名思义,他是Source RPM的意思,也就是这个RPM档案里面含有原始码哩!特别注意的是,这个 SRPM所提供的软体内容『并没有经过编译』,它提供的是原始码喔!

通常SRPM的副档名是以***.src.rpm这种格式来命名的。不过,既然SRPM提供的是原始码,那么为什么我们不使用Tarball直接来安装就好了?这是因为SRPM虽然内容是原始码,但是他仍然含有该软体所需要的相依性软体说明、以及所有RPM档案所提供的资料。同时,他与RPM不同的是,他也提供了参数设定档(就是configure与makefile)。所以,如果我们下载的是SRPM ,那么要安装该软体时,你就必须要:

  1. 先将该软体以RPM 管理的方式编译,此时SRPM 会被编译成为RPM 档案;
  2. 然后将编译完成的RPM 档案安装到Linux 系统当中

怪了,怎么SRPM这么麻烦呐!还要重新编译一次,那么我们直接使用RPM来安装不就好了?通常一个软体在释出的时候,都会同时释出该软体的RPM与SRPM 。我们现在知道RPM档案必须要在相同的Linux环境下才能够安装,而SRPM既然是原始码的格式,自然我们就可以透过修改SRPM内的参数设定档,然后重新编译产生能适合我们Linux环境的RPM档案,如此一来,不就可以将该软体安装到我们的系统当中,而不必与原作者打包的Linux环境相同了?这就是SRPM的用处了

三、 什么是i386, i586, i686, noarch, x86_64

从上面的说明,现在我们知道RPM 与SRPM 的格式分别为:

xxxxxxxxx.rpm    <==RPM的格式,已经经过编译且包装完成的rpm档案;
xxxxx.src.rpm    <==SRPM的格式,包含未编译的原始码资讯。

那么我们怎么知道这个软体的版本、适用的平台、编译释出的次数呢?只要透过档名就可以知道了!例如 rp-pppoe-3.11-5.el7.x86_64.rpm 这的档案的意义为:

rp-pppoe - 3.11 - 5 .el7.x86_64 .rpm

软体名称软体的版本资讯释出的次数适合的硬体平台副档名

除了后面适合的硬体平台与副档名外,主要是以『-』来隔开各个部分,这样子可以很清楚的发现该软体的名称、 版本资讯、打包次数与操作的硬体平台!好了,来谈一谈每个不同的地方吧:

  • 软体名称: 当然就是每一个软体的名称了!上面的范例就是rp-pppoe 。

  • 版本资讯: 每一次更新版本就需要有一个版本的资讯,否则如何知道这一版是新是旧?这里通常又分为主版本跟次版本。以上面为例,主版本为3 ,在主版本的架构下更动部分原始码内容,而释出一个新的版本,就是次版本啦!以上面为例,就是11啰!所以版本名就为3.11

  • 释出版本次数: 通常就是编译的次数啦!那么为何需要重复的编译呢?这是由于同一版的软体中,可能由于有某些bug或者是安全上的顾虑,所以必须要进行小幅度的patch或重设一些编译参数。设定完成之后重新编译并打包成RPM档案!因此就有不同的打包数出现了!

  • 操作硬体平台: 这是个很好玩的地方,由于RPM可以适用在不同的操作平台上,但是不同的平台设定的参数还是有所差异性!并且,我们可以针对比较高阶的CPU来进行最佳化参数的设定,这样才能够使用高阶CPU所带来的硬体加速功能。所以就有所谓的i386, i586, i686, x86_64与noarch等的档案名称出现了!

平台名称 适合平台说明
i386 几乎适用于所有的x86 平台,不论是旧的Pentium 或者是新的Intel Core 2 与 K8 系列的CPU 等等,都可以正常的工作!那个i 指的是Intel 相容的CPU 的意思,至于386 不用说,就是CPU 的等级啦!
i586 就是针对586 等级的电脑进行最佳化编译。那是哪些CPU 呢?包括Pentium 第一代MMX CPU, AMD 的K5, K6 系列CPU (socket 7 插脚) 等等的CPU 都算是这个等级;
i686 在Pentium II 以后的Intel 系列CPU ,及K7 以后等级的CPU 都属于这个686 等级!由于目前市面上几乎仅剩P-II 以后等级的硬体平台,因此很多distributions 都直接释出这种等级的RPM 档案。
x86_64 针对64 位元的CPU 进行最佳化编译设定,包括Intel 的Core 2 以上等级CPU ,以及AMD 的Athlon64 以后等级的CPU ,都属于这一类型的硬体平台。
noarch 就是没有任何硬体等级上的限制。一般来说,这种类型的RPM 档案,里面应该没有binary program 存在, 较常出现的就是属于shell script 方面的软体。

截至目前为止(2015),就算是旧的个人电脑系统,堪用与能用的设备大概都至少是Intel Core 2以上等级的电脑主机,泰半都是64位元的系统了!因此目前CentOS 7仅推出x86_64的软体版本,并没有提供i686以下等级的软体了!如果你的系统还是很老旧的机器,那才有可能不支援64位元的Linux系统。此外,目前仅存的软体版本大概也只剩下i686及x86_64还有不分版本的noarch而已, i386只有在某些很特别的软体上才看到的到啦!

受惠于目前x86系统的支援方面,新的CPU都能够执行旧型CPU所支援的软体,也就是说硬体方面都可以向下相容的,因此最低等级的i386软体可以安装在所有的x86硬体平台上面,不论是32位元还是64位元。但是反过来说就不行了。举例来说,目前硬体大多是64位元的等级,因此你可以在该硬体上面安装x86_64或i386等级的RPM软体。但在你的旧型主机,例如P-III/P-4 32位元机器上面,就不能够安装x86_64的软体!

根据上面的说明,其实我们只要选择i686 版本来安装在你的x86 硬体上面就肯定没问题。但是如果强调效能的话, 还是选择搭配你的硬体的RPM 档案吧!毕竟该软体才有针对你的CPU 硬体平台进行过参数最佳化的编译嘛!

四、 RPM 的优点

由于RPM 是透过预先编译并打包成为RPM 档案格式后,再加以安装的一种方式,并且还能够进行资料库的记载。所以RPM 有以下的优点:

  • RPM 内含已经编译过的程式与设定档等资料,可以让使用者免除重新编译的困扰;
  • RPM 在被安装之前,会先检查系统的硬碟容量、作业系统版本等,可避免档案被错误安装;
  • RPM 档案本身提供软体版本资讯、相依属性软体名称、软体用途说明、软体所含档案等资讯,便于了解软体; R* PM 管理的方式使用资料库记录RPM 档案的相关参数,便于升级、移除、查询与验证。

为什么RPM 在使用上很方便呢?我们前面提过, RPM 这个软体管理员所处理的软体,是由软体提供者在特定的 Linux 作业平台上面将该软体编译完成并且打包好。那使用者只要拿到这个打包好的软体, 然后将里头的档案放置到应该要摆放的目录,不就完成安装啰?对啦!就是这样!

但是有没有想过,我们在前一章里面提过的,有些软体是有相关性的,例如要安装网路卡驱动程式,就得要有 kernel source 与gcc 及make 等软体。那么我们的RPM 软体是否一定可以安装完成呢?如果该软体安装之后,却找不到他相关的前驱软体, 那不是挺麻烦的吗?因为安装好的软体也无法使用啊!

为了解决这种具有相关性的软体之间的问题(就是所谓的软体相依属性),RPM就在提供打包的软体时,同时加入一些讯息登录的功能,这些讯息包括软体的版本、打包软体者、相依属性的其他软体、本软体的功能说明、本软体的所有档案记录等等,然后在Linux系统上面亦建立一个RPM软体资料库,如此一来,当你要安装某个以RPM型态提供的软体时,在安装的过程中, RPM会去检验一下资料库里面是否已经存在相关的软体了,如果资料库显示不存在,那么这个RPM档案『预设』就不能安装。呵呵!没有错,这个就是RPM类型的档案最为人所诟病的『软体的属性相依』问题啦!

五、 RPM 属性相依的克服方式: YUM 线上升级

为了重复利用既有的软体功能,因此很多软体都会以函式库的方式释出部分功能,以方便其他软体的呼叫应用, 例如PAM 模组的验证功能。此外,为了节省使用者的资料量,目前的distributions 在释出软体时, 都会将软体的内容分为一般使用与开发使用(development) 两大类。所以你才会常常看到有类似 pam-xxrpm 与pam-devel-xxrpm 之类的档名啊!而预设情况下,大部分的software-devel-xxrpm 都不会安装,因为终端用户大部分不会去开发软体嘛!

因为有上述的现象,因此RPM 软体档案就会有所谓的属性相依的问题产生(其实所有的软体管理几乎都有这方面的情况存在)。那有没有办法解决啊?前面不是谈到RPM 软体档案内部会记录相依属性的资料吗?那想一想,要是我将这些相依属性的软体先列表, 在有要安装软体需求的时候,先到这个列表去找,同时与系统内已安装的软体相比较,没安装到的相依软体就一口气同时安装起来, 那不就解决了相依属性的问题了吗?有没有这种机制啊?有啊!那就是YUM 机制的由来!

CentOS (1)先将释出的软体放置到YUM 伺服器内,然后(2)分析这些软体的相依属性问题,将软体内的记录资讯写下来(header)。然后再将这些资讯分析后记录成软体相关性的清单列表。这些列表资料与软体所在的本机或网路位置可以称呼为容器或软体仓库或软体库(repository)。当用户端有软体安装的需求时,用户端主机会主动的向网路上面的yum 伺服器的软体库网址下载清单列表, 然后透过清单列表的资料与本机RPM 资料库已存在的软体资料相比较,就能够一口气安装所有需要的具有相依属性的软体了。整个流程可以简单的如下图说明:

当用户端有升级、安装的需求时, yum 会向软体库要求清单的更新,等到清单更新到本机的/var/cache/yum 里面后, 等一下更新时就会用这个本机清单与本机的RPM 资料库进行比较,这样就知道该下载什么软体。接下来yum 会跑到软体库伺服器 (yum server) 下载所需要的软体(因为有记录软体所在的网址),然后再透过RPM 的机制开始安装软体啦!这就是整个流程!谈到最后,还是需要动到RPM 的啦!所以下个小节就让我们来谈谈RPM 这咚咚吧!

为什么要做出『软体库』呢?由于yum 伺服器提供的RPM 档案内容可能有所差异,举例来说,原厂释出的资料有(1)原版资料; (2)更新资料(update); (3)特殊资料(例如第三方协力软体,或某些特殊功能的软体)。这些软体档案基本上不会放置到一起,那如何分辨这些软体功能呢?就用『软体库』的概念来处理的啦!不同的『软体库』网址,可以放置不同的功能的软体之意!

参考资料

药企,独角兽,苏州。团队长期招人,感兴趣的都可以发邮件聊聊:tiehan@sina.cn
个人公众号,比较懒,很少更新,可以在上面提问题,如果回复不及时,可发邮件给我: tiehan@sina.cn