rpm包管理

1. rpm包管理器概述

源码到程序包的转换过程

rpm包管理_...

    rpmRedhat公司针对自己的操作系统RHEL提出的一种管理软件包的方法,rpm原来全称为RedHat Package Manager,后来由于rpm包管理器的使用方便以及Redhat公司采取各种商业策略,使得rpm成为了工业标准,其他系统可借鉴使用rpm,因此rpm全称后来改为:RPM Package Manager。在系统上只要安装了rpm包管理器,那么只要符合rpm标准的程序包文件都可以实现更为方便地安装、升级、卸载和查询等管理操作。

为什么要使用rpm

    Linux的哲学思想之一是一个程序只做一件事,并且做好因此Linux经常通过使用众多功能单一的程序来完成复杂任务,最常见的例子是管道命令的使用。而各个程序功能的单一,带来的问题是各个程序文件之间的产生了极大的依赖性,这是一个需要解决的问题。此外,要安装各种功能的程序,而各程序在安装时的路径、生成的文件各不相同,这给卸载某程序将带来极×××烦,极不方便管理,以及对程序的版本的管理等。在Linux上只要安装rpm包管理器即可解决以上问题,rpm包管理器可将编译好的各个应用程序组成文件打包成一个或有限个rpm程序包,每个包中会记录当前包的依赖性。一旦程序包安装了之后,rpm会追踪其各个文件的安装路径(包括程序运行时产生的临时文件)。rpm包管理器就是通过这种方式来实现对rpm程序包的管理的,而对程序包的管理无外乎是安装、升级、卸载、查询等操作。

2. 程序包管理器的组成部分

程序包管理器由程序包组成清单数据库两部分组成:

(1)程序包的组成清单(每个程序都单独实现):

    文件清单

    安装或卸载时运行的脚本

(2)数据库(为所有rpm程序包所共用):

    程序包的名称和版本

    依赖关系

    功能说明

    安装生成的各个文件的文件路径及校验码信息

3. rpm包命名格式

    rpm包有主包支包(主包的子包)之分,支包作为主包的功能性补充。其中rpm主包的命名格式为:name-VERSION-release.arch.rpm。各个部分解释如下:

name程序名

VERSION版本

    VERSION由三部分组成:

    major程序的主版本号

    minor程序的次版本号

    release程序的修订号

release[.os].arch代表rpm包的发行号

    release[.os]rpm版本+操作系统

    archarchetecture,支持的硬件架构。常见的硬件架构有i386, x64(amd64), ppc, noarch(支持任何架构)

各组成部分示意图如下:

rpm包管理_..._02

举个例子,zsh-5.0.2-25.el7.x86_64.rpm代表:该zsh程序包的主版本号为5,次版本号为0,修订号为2rpm的版本号为25,支持的操作系统是RHEL 7(CentOS 7),支持的硬件架构是x86_64

对于支包来说,其命名格式为:

name-function-VERSION-release.arch.rpm

常见的function有:devel, utils(工具程序), libs, ...

4. 获取程序包的途径

如何获取rpm包呢?

(1)系统发行版的光盘或官方的文件服务器(或镜像站点)

    常见的镜像网站如:

    http://mirrors.aliyun.com

    http://mirrors.sohu.com

    http://mirrors.163.com

(2)项目的官方站点

(3)第三方组织

  (3)第三方组织

   (a)EPEL

    (b)搜索引擎

    http://pkgs.org

    http://rpmfind.net

    http://rpm.pbone.net

        ...

(4)自己制作rpm

建议:检查其合法性(来源合法性、程序包的完整性)

 

5. CentOS系统上rpm命令管理程序包

5.1. 安装

语法格式:

    rpm {-i|--install} [install-options] PACKAGE_FILE ...

 

常用命令选项:

    -vverbose,输出详细的过程信息;

    -vvvery verbose,输出更为详细的过程信息;

 

安装选项(install-options)

    -hhash marks输出进度条;hash标记符为#,每个#表示2%的进度;

    --test测试安装,检查并报告依赖关系及冲突信息等;相当于dry run

    --nodeps忽略依赖关系,不建议使用;

    --replacepkgs重新安装;

    --noscripts指定不运行脚本;

    --nosignature不检查包签名信息,即不检查程序包的来源合法性;

    --nodigest不检查包完整性信息;

 

用法:

    rpm -ivh PACKAGE_FILE ...

 

注意:rpm可以自带脚本

最多有四类脚本:(--noscripts可指定不运行这四类脚本)

preinstall安装过程开始之前运行的脚本,%pre--nopre可指定不运行;

postinstall安装过程完成之后运行的脚本,%post--nopost可指定不运行;

preuninstall卸载过程真正开始执行之前运行的脚本,%preun--nopreun可指定不运行;

postuninstall卸载过程完成之后运行的脚本,%postun--nopostun可指定不运行;

 

命令演示:

安装zsh,首先挂载光盘:

[root@osyunwei ~]# mkdir /media/cdrom

[root@osyunwei ~]# mount /dev/sr0 /media/cdrommount: block device /dev/sr0 is write-protected, mounting read-only

rpm下载zsh

[root@osyunwei ~]# cd /media/cdrom/Packages/

[root@osyunwei Packages]# rpm -ivh zsh-4.3.11-4.el6.centos.2.x86_64.rpm Preparing...                ########################################### [100%]
   1:zsh                    ########################################### [100%]

 

5.2. 升级

语法格式:

    rpm {-U|--upgrade} [install-options] PACKAGE_FILE ...

    rpm {-F|--freshen} [install-options] PACKAGE_FILE ...

 

常用选项:

    -U升级或安装;

    -F升级;

    -v安装

    -vv安装”.

 

安装选项(install-options)

    --oldpackage降级 --> 某些程序升级后遇到不兼容的情况,此时需要降级;

    --force强制升级 --> 某些程序升级后会引起依赖性问题,此时可能会用到此选项;

    

    其他安装选项同安装

 

用法:

    rpm -Uvh PACKAGE_FILE ...

    rpm -Fvh PACKAGE_FILE ...

 

注意:

1Linux支持多内核版本并存,所以不要对内核做升级操作,因为这样有可能会导致无法回滚,建议直接安装新版本内核即可。

2)如果某原程序包的配置文件安装后曾被修改过,则在升级时,新版本的程序提供的同一个配置文件不会覆盖原有版本的配置文件,而是把新版本的配置文件重命名(FILENAME.rpmnew)后提供;

 

命令演示:

查看当前已安装的zsh的版本:

[root@osyunwei ~]# rpm -q zshzsh-4.3.11-4.el6.centos.2.x86_64

从网易镜像站点下载zsh-5.0.2-25.el7_3.1.x86_64.rpm程序包:

[root@osyunwei ~]# wget http://mirrors.163.com/centos/7/updates/x86_64/Packages/zsh-5.0.225.el7_3.1.x86_64.rpm

rpm升级zsh

[root@osyunwei ~]# rpm -Uvh zsh-5.0.2-25.el7_3.1.x86_64.rpm warning: zsh-5.0.2-25.el7_3.1.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5: NOKEY
error: Failed dependencies:
libc.so.6(GLIBC_2.14)(64bit) is needed by zsh-5.0.2-25.el7_3.1.x86_64
libc.so.6(GLIBC_2.15)(64bit) is needed by zsh-5.0.2-25.el7_3.1.x86_64

发现有依赖关系导致无法升级。

此时若要强行升级可使用--nodeps选项:

[root@osyunwei ~]# rpm -Uvh --nodeps zsh-5.0.2-25.el7_3.1.x86_64.rpmwarning: zsh-5.0.2-25.el7_3.1.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5: NOKEY
Preparing...                ########################################### [100%]
   1:zsh                    ########################################### [100%]

注意:忽略依赖性升级后程序不一定能正常运行!

再将zsh降级:

[root@osyunwei ~]# cd /media/cdrom/Packages/

[root@osyunwei Packages]# rpm -Uvh --oldpackage zsh-4.3.11-4.el6.centos.2.x86_64.rpm Preparing...                ########################################### [100%]
   1:zsh                    ########################################### [100%]

 

5.3. 卸载

语法格式:

    rpm {-e|--erase} [--allmatches] [--nodeps] [--test] PACKAGE_NAME ...

卸载选项(erase options)

    --allmatches卸载所有匹配指定名称的程序包的各版本;

    --nodeps忽略依赖关系;

    --test测试卸载,dry run模式。

 

用法:

    rpm -e PACKAGE_NAME

 

命令演示:

 

卸载已安装的zsh程序包:

[root@osyunwei ~]# rpm -e zsh

如果没有任何显示就说明卸载成功了!

 

5.4. 查询

语法格式:

    rpm {-q|--query} [select-options] [query-options]

 

[select-options]

    PACKAGE_NAME查询指定的程序包是否安装,及其版本;

    -a, --all查询所有已经安装过的包;

    -f, --file FILE查询指定的文件由哪个程序包安装生成;

    -p, --package PACKAGE_FILE用于实现对未安装的程序包执行查询操作;

    --whatprovides CAPABILITY查询指定的CAPABILITY由哪个程序包提供;

    --whatrequires CAPABILITY查询指定的CAPABILITY被哪个包所依赖。

 

[query-options]

    --changelog查询rpm包的changelog

    -i, --info程序包相关的信息,版本号、大小、所属的包组等

    -l, --list程序包安装生成的所有文件列表;

    -c, --configfiles查询指定的程序包提供的配置文件;

    -d, --docfiles查询指定的程序包提供的文档;

    --provides列出指定的程序包提供的所有的CAPABILITY

    -R, --requires查询指定的程序包的依赖关系;

    --scripts查看程序包自带的脚本片段。

 

用法:

    rpm -qi PACKAGE

    rpm -qf FILE

    rpm -qc PACKAGE

    rpm -qd PACKAGE

    rpm -qpi PACKAGE_FILE

    rpm -apl PACKAGE_FILE

    rpm -qpc PACKAGE_FILE

列了这么多个选项,不如来个实例吧!

(1)查看zsh是否已经安装:

[root@osyunwei ~]# rpm -qa | grep '^zsh'zsh-4.3.11-4.el6.centos.2.x86_64    //显示已安装zsh
或:[root@osyunwei ~]# rpm -q zshzsh-4.3.11-4.el6.centos.2.x86_64    //显示已安装zsh

 

(2)查询/etc/fstab由哪个程序包安装生成:

[root@osyunwei ~]# rpm -qf /etc/fstab setup-2.8.14-20.el6_4.1.noarch

 

(3)列出安装httpd生成的所有文件列表:

[root@osyunwei ~]# rpm -ql httpd

 

(4)列出httpd程序包的依赖关系:

[root@osyunwei ~]# rpm -qR httpd/bin/bash  
/bin/sh  
.....(
省略).....
libz.so.1()(64bit)  rpmlib(CompressedFileNames) <= 3.0.4-1.....(
省略).....
rpmlib(VersionedDependencies) <= 3.0.3-1
rtld(GNU_HASH)  system-logos >= 7.92.1-1
rpmlib(PayloadIsXz) <= 5.2-1

 

(5)查看httpd程序包提供的文档:

[root@osyunwei ~]# rpm -qd httpd/usr/share/doc/httpd-2.2.15/ABOUT_APACHE
/usr/share/doc/httpd-2.2.15/CHANGES
/usr/share/doc/httpd-2.2.15/LICENSE
/usr/share/doc/httpd-2.2.15/NOTICE
/usr/share/doc/httpd-2.2.15/README
/usr/share/doc/httpd-2.2.15/VERSIONING
/usr/share/man/man8/apachectl.8.gz
/usr/share/man/man8/htcacheclean.8.gz
/usr/share/man/man8/httpd.8.gz
/usr/share/man/man8/rotatelogs.8.gz
/usr/share/man/man8/suexec.8.gz

 

(6)查询httpd程序包提供的配置文件:

[root@osyunwei ~]# rpm -qc httpd/etc/httpd/conf.d/welcome.conf
/etc/httpd/conf/httpd.conf
/etc/httpd/conf/magic
/etc/logrotate.d/httpd
/etc/sysconfig/htcacheclean
/etc/sysconfig/httpd
/var/www/error/HTTP_BAD_GATEWAY.html.var
/var/www/error/HTTP_BAD_REQUEST.html.var.....(
以下省略).....

 

(7)查看httpd程序包自带的脚本片段:

[root@osyunwei ~]# rpm -q --scripts httpd

 

(8)列出bash程序包提供的所有的CAPABILITY

[root@osyunwei ~]# rpm -q --provides bashconfig(bash) = 4.1.2-40.el6bash = 4.1.2-40.el6
bash(x86-64) = 4.1.2-40.el6

 

(9)查看httpd程序包提供的所有的CAPABILITY

[root@osyunwei ~]# rpm -q --provides httpdconfig(httpd) = 2.2.15-53.el6.centos
httpd-mmn = 20051115
httpd-suexec = 2.2.15-53.el6.centos.....(
中间省略).....
mod_vhost_alias.so()(64bit)  webserver  
.....(
以下省略).....

 

(10)查询指定的CAPABILITY (这里为webserver)由哪个程序包提供:

[root@osyunwei ~]# rpm -q --whatprovides webserverhttpd-2.2.15-53.el6.centos.x86_64

 

(11)查询指定的CAPABILITY (这里为bash)被哪个包所依赖:

[root@osyunwei ~]# rpm -q --whatrequires bashjline-0.9.94-0.8.el6.noarch
initscripts-9.03.53-1.el6.centos.x86_64
dracut-004-409.el6.noarch
lvm2-2.02.143-7.el6.x86_64
rsyslog-5.8.10-10.el6_6.x86_64
cronie-1.4.4-15.el6_7.1.x86_64
autofs-5.0.5-122.el6.x86_64
eclipse-pde-3.6.1-6.13.el6.x86_64

 

(12)查看bash的更新日志(changelog)

[root@osyunwei ~]# rpm -q --changelog bash...
* Fri Oct 17 1997 Donnie Barnes <djb@redhat.com>- added BuildRoot
* Tue Jun 03 1997 Erik Troan <ewt@redhat.com>- built against glibc

 

(13)查看程序包相关的信息,版本号、大小、所属的包组等:

[root@osyunwei ~]# rpm -qi zsh

5.5. 校验

用途:可检查程序包中的数据是否被修改过。

 

语法格式:

    rpm {-V|--verify} [select-options] [verify-options]

 

用法:

    rpm -V PACKAGE_NAME

 

校验属性:

S file Size differs
M Mode differs (includes permissions and file type)5 digest (formerly MD5 sum) differs
D Device major/minor number mismatch
L readLink(2) path mismatch
U User ownership differs
G Group ownership differs
T mTime differs
P caPabilities differ

 

命令演示:

 

修改zsh程序包的配置文件,首先查看zsh程序包的配置文件有哪些:

[root@osyunwei ~]# rpm -qc zsh/etc/skel/.zshrc
/etc/zlogin
/etc/zlogout
/etc/zprofile
/etc/zshenv
/etc/zshrc

 

vim修改/etc/zshrc文件,在首行添加一个'#'字符,然后再用-V选项检验:

[root@osyunwei ~]# vim /etc/zshrc

[root@osyunwei ~]# rpm -V zshS.5....T.  c /etc/zshrc

显然,文件/etc/zshrc的大小、md5值、时间戳(mtime)发生了变化。

 

5.6. 数据库重建

默认rpm管理器的数据库路径为/var/lib/rpm,刚才的查询操作正是通过此处的数据库进行。

 

获取帮助:

    CentOS 6man rpm

    CentOS 7man rpmdb

 

语法格式:

    rpm {--initdb|--rebuilddb} [-v] [--dbpath DIRECTORY] [--root DIRECTORY]

    

常用选项:

    --initdb初始化数据库,当前无任何数据库可初试化创建一个新的数据库;当前有时不执行任何操作;

    --rebuilddb重新构建,通过遍历读取当前系统上所有已经安装过的程序包进行重新创建;

 

命令演示:

 

/tmp/mydb目录下创建初始化数据库:

[root@osyunwei ~]# rpm --initdb --dbpath /tmp/mydb[root@osyunwei ~]# ls /tmp/mydb/__db.001  __db.002  __db.003  __db.004  Packages

 

/tmp/mydb目录下重新创建数据库:

[root@osyunwei ~]# rpm --rebuilddb --dbpath /tmp/mydb[root@osyunwei ~]# ls /tmp/mydb/Packages

注意:不一定能够重建完整的数据库,所以慎用该命令吧!

 

5.7. 包来源合法性验证和完整性验证

 

首先要了解一下什么是数字签名?

    数字签名就是用本地密钥去加密对应数据的特征码。

    程序包开发者将程序包制作好之后,采用单向加密算法对程序包进行计算,得到定长特征码,再用私钥对这段定长特征值进行加密,并将加密过的特征码附于程序包尾部,这就是数字签名。程序使用者先得到开发者的公钥,用于解密特征码,如果解密成功,说明来源合法;然后使用者在本地对该程序包用单向加密算法再次计算出定长特征码,如果使用者计算出的特征码和程序开发者提供的特征码相同,则说明程序数据完整。虽然用了两种加密算法,但却没有保密性的概念,而是作为验证。

    特征码有没有被篡改的可能性?假设中间人得到程序包的特征值后,想篡改特征码,但篡改后需要用本地私钥进行加密,因此来源就不合法了,更不用谈完整性了,所以特征码是无法修改的。

    但存在一个问题,就是使用者如何获得正确的公钥?这要求下载公钥的网站的正确性以及数据在网络传输过程中的安全性,涉及网络安全问题。

图解数字签名

rpm包管理_..._03

对于CentOS发行版来说,假设已获取正确的公钥,那么导入信任的包制作者的公钥(或签名密钥)操作如下:

rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

 

两种验证方式:

1)安装此组织签名的程序时,程序内部会自动执行验证。

2)手动验证:rpm -K PACKAGE_FILE,同样由程序内部自行执行校验操作。

 

命令演示:

 

校验zsh程序包的来源合法性及数据完整性:

[root@osyunwei Packages]# rpm -K zsh-4.3.11-4.el6.centos.2.x86_64.rpm zsh-4.3.11-4.el6.centos.2.x86_64.rpm: rsa sha1 (md5) pgp md5 OK    //校验通过;