一、RPM的简介
由于程序源代码到可被计算机识别并运行的指令是需要多步骤处理的:程序源代码 --> 预处理 --> 编译 --> 汇编 --> 链接。
这里以C,C++为例做为说明。程序员写完C,C++源代码后需要把源代码进行预处理,即通过预处理器把源代码分割或处理成为特定的符号用来支持宏调用。预处理后进一步通过编译器(gcc)编译为目标代码(object code),它由接近于机器语言的代码组成。目标代码通过编译器编译后才能生成可供CPU识别的机器代码、机器指令。由于C,C++在编写中大量调用了库文件,所以在编译后需要把源代码中使用到的库做好链接。形成能够依赖于共享库独立运行代码。
由源代码到可被计算机运行的代码需要预处理、编译、汇编、链接等过程。对于刚接触LINUX或接触不深的我们来说是一件不可想象的事。所以有很多志愿者或机构把源代码编译成可被计算机识别的二进制应用程序打包发布到网络上供用户下载使用。打包的二进制应用程序一般包含(二进制文件、库文件、配置文件、帮助文件)。由于在LINUX中二进制应用程序的组成部分为:
二进制程序:/bin, /sbin, /usr/bin, /usr/sbin, /usr/local/bin, /usr/local/sbin
库文件:/lib, /lib64, /usr/lib, /usr/lib64, /usr/local/lib, /usr/local/lib64
配置文件:/etc, /etc/DIRECTORY, /usr/local/etc
帮助文件:/usr/share/man, /usr/share/doc, /usr/local/share/man, /usr/local/share/doc
此时当用户拿到编译好的二进制应用程序后,需要手动分配不同类型的文件,而且当我们要卸载的时候需要去删除之前的文件。这样会大大造成不必要的麻烦。就此有了程序包管理的出现。
RPM,全称RPM Package Manager,是由Red Hat推出的软件包管理系统,现在在各个发行版普遍使用。RPM包管理器,将编译好的程序打包成一个文件或有限的几个文件,可用于实现便捷地安装、卸载、升级、查询、校验等程序管理;通常用与RHEL,红帽衍生系统,如CenOS等系统,用来实现对Linux程序包进行快捷管理。
①、程序的组成组成清单 (每个包独有):文件清单、安装或卸载时运行的脚本
②、数据库(公共):程序包名称及版本、依赖关系、功能说明、安装生成的各文件的文件路径及校验码信息
RPM命名格式为:
[root@localhost Packages]# ll zsh-html-4.3.10-7.el6.x86_64.rpm -r--r--r--. 2 root root 465040 11月 25 2013 zsh-html-4.3.10-7.el6.x86_64.rpm #rpm包命名方式:name-version(major.minor.release)-rpm.release(rpm.release.OS).arch.rpm
以上rpm包:rpm包名字为zsh-html,zsh-html程序主版本号为4,zsh-html程序次版本号为3,zsh-html程序释放版本号为10,rpm包BUG或其他功能修复版本号为7,el6为企业LINUX版本6,x86_64为平台架构
二、2进制程序所依赖的库文件
由于程序包安装或使用中会大连调用库文件。所以介绍一下两个命令。以便以后方便查看程序二进制程序所依赖的库文件。
查看二进制程序所依赖的库文件:
[root@localhost Packages]# ldd /bin/ls linux-vdso.so.1 => (0x00007ffff09ff000) libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fd567b05000) librt.so.1 => /lib64/librt.so.1 (0x00007fd5678fd000) libcap.so.2 => /lib64/libcap.so.2 (0x00007fd5676f8000) libacl.so.1 => /lib64/libacl.so.1 (0x00007fd5674f0000) libc.so.6 => /lib64/libc.so.6 (0x00007fd56715c000) libdl.so.2 => /lib64/libdl.so.2 (0x00007fd566f57000) /lib64/ld-linux-x86-64.so.2 (0x00007fd567d2a000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fd566d3a000) libattr.so.1 => /lib64/libattr.so.1 (0x00007fd566b35000) # 依赖的库名 => 依赖的库的路径(在内存中的位置)
查看本机装载的库文件:
[root@localhost Packages]# ldconfig -p 在缓冲区“/etc/ld.so.cache”中找到 248 个库 libz.so.1 (libc6,x86-64) => /lib64/libz.so.1 libxtables.so.4 (libc6,x86-64) => /lib64/libxtables.so.4 ........ libxml2.so.2 (libc6,x86-64) => /usr/lib64/libxml2.so.2
三、RPM的使用详细介绍
前面说了一大堆。好吧。现在开始我们的命令之旅吧!!下面为RPM管理中常见的使用!!
①、RPM包的安装
rpm {-i|--install} [install-options] PACKAGE_FILE ...
-v: 显示安装过程
-h: 以#显示程序包管理执行进度;每个#表示2%的进度
[root@localhost Packages]# rpm -ivh zsh-html-4.3.10-7.el6.x86_64.rpm Preparing... ########################################### [100%] 1:zsh-html ########################################### [100%]
--test:测试安装,但不真正执行安装过程,dry run模式
[root@localhost Packages]# rpm -ivh --test uuid-c++-devel-1.6.1-10.el6.i686.rpm error: Failed dependencies: libossp-uuid++.so.16 is needed by uuid-c++-devel-1.6.1-10.el6.i686 uuid-c++ = 1.6.1-10.el6 is needed by uuid-c++-devel-1.6.1-10.el6.i686 uuid-devel = 1.6.1-10.el6 is needed by uuid-c++-devel-1.6.1-10.el6.i686 #这里,我们使用了--test测试安装。但是报错了error: Failed dependencies。这是由于安装的包依赖于其它包导致的 #可以先安装其他依赖的包或者使用下面参数忽略忽略依赖关系安装。但是一般不建议这么做。
--nodeps:忽略依赖关系安装
[root@localhost Packages]# rpm -ivh --nodeps uuid-c++-devel-1.6.1-10.el6.i686.rpm Preparing... ########################################### [100%] 1:uuid-c++-devel ########################################### [100%] #上面测试安装的时候由于包的依赖关系无法安装。这里我们忽略依赖关系即可成功安装,但是一般不推荐这么做。 #忽略依赖关系安装一般使用场景。比如两个包互相依赖,我依赖你,你依赖我,这是要结为夫妻的节奏。此时可以使用 #忽略关系先安装一个包,然后安装另一个包
--replacepkgs: 重新安装
[root@localhost Packages]# rpm -ivh --replacepkgs zsh-html-4.3.10-7.el6.x86_64.rpm Preparing... ########################################### [100%] 1:zsh-html ########################################### [100%] #注意事项:重新安装可能存在新的配置文件覆盖之前的配置文件。所以建议重新安装前备份一下配置文件。
--nosignature: 不检查来源合法性
--nodigest:不检查包完整性
[root@localhost Packages]# rpm -ivh --nosignature --nodigest zsh-html-4.3.10-7.el6.x86_64.rpm Preparing... ########################################### [100%] package zsh-html-4.3.10-7.el6.x86_64 is already installed #由于rpm包是第三方为我们提供的。所以为了安装的可靠性。在没有导入官方密钥的时候我们安装是会有警告提示的
--noscripts:不执行程序包脚本片断,包含以下四个脚本
--nopre: 安装前脚本(例如安装某个程序的时候,需要特定的用户去安装,而我们系统没有此用户,此时就需要写一个安装前脚本来创建此用户,以便执行后面的程序包安装)
--nopost:安装后脚本
--nopreun:卸载前脚本
--nopostun:卸载后脚本
[root@localhost Packages]# rpm -ivh --test --noscripts --nopre --nopost --nopreun --nopostun #zsh-html-4.3.10-7.el6.x86_64.rpm Preparing... ########################################### [100%] package zsh-html-4.3.10-7.el6.x86_64 is already installed #以上命令没有实际用途。一般添加需要忽略的脚本的参数即可。这里只是提供测试。
②、RPM包的升级
rpm {-U|--upgrade} [install-options] PACKAGE_FILE ...
upgrage:安装有旧版程序包,则“升级”;如果不存在旧版程序包,则“安装”
rpm {-F|--freshen} [install-options] PACKAGE_FILE ...
freeshen:安装有旧版程序包,则“升级”;如果不存在旧版程序包,则不执行升级
-v: 显示安装过程
-h: 以#显示程序包管理执行进度;每个#表示2%的进度
[root@localhost Packages]# rpm -e zsh-html [root@localhost Packages]# rpm -Fvh zsh-html-4.3.10-7.el6.x86_64.rpm [root@localhost Packages]# rpm -Uvh zsh-html-4.3.10-7.el6.x86_64.rpm Preparing... ########################################### [100%] 1:zsh-html ########################################### [100%] #这里我们卸载zsh-html。然后使用rpm -Fvh进行升级。因为不存在旧版程序包,所以不执行升级。 #而rpm -Uvh在不存在旧版程序包时,会对此程序包进行安装。
--oldpackage:降级;
--force: 强行升级;
升级注意事项:如果原程序包的配置文件安装后曾被修改,升级时,新版本的提供的同一个配置文件并不会直接覆盖老版本的配置文件,而把新版本的文件重命名(FILENAME.rpmnew)后保留
③、RPM包的查询
rpm {-q|--query} [select-options] [query-options]
[select-options]
-a: 查询当前系统安装的所有包
[root@localhost Packages]# rpm -qa gnutls-2.8.5-18.el6.x86_64 setup-2.8.14-20.el6_4.1.noarch ........ libthai-0.1.12-3.el6.x86_64
-f: 查看指定的文件由哪个程序包安装生成
[root@localhost Packages]# rpm -qf /bin/bash bash-4.1.2-15.el6_4.x86_64
-p:针对尚未安装的程序包文件做查询操作
[root@localhost Packages]# rpm -qpl php-dba-5.3.3-26.el6.x86_64.rpm /etc/php.d/dba.ini /usr/lib64/php/modules/dba.so #rpm -qp可以配合[query-options]选项来查询未安装包的信息
--whatrequires CAPABILITY:查询指定的CAPABILITY被哪个包所依赖
[root@localhost Packages]# rpm -q --whatrequires /bin/bash glibc-common-2.12-1.132.el6.x86_64 ca-certificates-2013.1.94-65.0.el6.noarch ........ groff-1.18.1.4-21.el6.x86_64
--whatprovides CAPABILITY:查询指定的CAPABILITY由哪个包所提供
[root@localhost Packages]# rpm -q --whatprovides /bin/bash bash-4.1.2-15.el6_4.x86_64
[query-options]
--changelog:查询rpm包的changlog。
[root@localhost Packages]# rpm -q --changelog zsh-html * 一 8月 05 2013 James Antill <[email protected]> - 4.3.10-7 - Change {NAME:OFFSET:LENGTH} substitution feature to ignore KSH_ARRAYS option. - Fixup tests. - Resolves: rhbz#820530
-c: 查询程序的配置文件
[root@localhost Packages]# rpm -qc bash /etc/skel/.bash_logout /etc/skel/.bash_profile /etc/skel/.bashrc
-d: 查询程序的文档
[root@localhost Packages]# rpm -qd bash /usr/share/doc/bash-4.1.2/COPYING /usr/share/info/bash.info.gz /usr/share/man/man1/..1.gz ........ /usr/share/man/man1/:.1.gz
-i: information(包的名称,版本,描述等信息)
[root@localhost Packages]# rpm -qi bash Name : bash Relocations: (not relocatable) Version : 4.1.2 Vendor: CentOS Release : 15.el6_4 Build Date: 2013年07月18日 星期四 21时21分24秒 Install Date: 2015年08月27日 星期四 14时53分45秒 Build Host: c6b10.bsys.dev.centos.org Group : System Environment/Shells Source RPM: bash-4.1.2-15.el6_4.src.rpm Size : 3139291 License: GPLv3+ Signature : RSA/SHA1, 2013年07月18日 星期四 21时46分10秒, Key ID 0946fca2c105b9de Packager : CentOS BuildSystem <http://bugs.centos.org> URL : http://www.gnu.org/software/bash Summary : The GNU Bourne Again shell Description : The GNU Bourne Again shell (Bash) is a shell or command language interpreter that is compatible with the Bourne shell (sh). Bash incorporates useful features from the Korn shell (ksh) and the C shell (csh). Most sh scripts can be run by bash without modification.
-l: 查看指定的程序包安装后生成的所有文件
[root@localhost Packages]# rpm -ql bash /bin/bash /bin/sh /etc/skel/.bash_logout ........ /etc/skel/.bash_profile
--scripts:程序包自带的脚本片断(这里可以看到上面提到的四类脚本)
[root@localhost Packages]# rpm -q --scripts bash postinstall scriptlet (using <lua>): bashfound = false; shfound = false; f = io.open("/etc/shells", "r"); ........ f:close() postuninstall scriptlet (using /bin/sh): if [ "$1" = 0 ]; then /bin/grep -v '^/bin/bash$' < /etc/shells | \ /bin/grep -v '^/bin/sh$' > /etc/shells.new /bin/mv /etc/shells.new /etc/shells fi
-R: 查询指定的程序包所依赖的CAPABILITY
[root@localhost Packages]# rpm -qR bash /bin/sh /bin/sh config(bash) = 4.1.2-15.el6_4 ........ libc.so.6()(64bit)
--provides: 列出指定程序包所提供的CAPABILITY
[root@localhost Packages]# rpm -q --provides bash config(bash) = 4.1.2-15.el6_4 bash = 4.1.2-15.el6_4 bash(x86-64) = 4.1.2-15.el6_4
④、RPM包的卸载
rpm {-e|--erase} [--allmatches] [--nodeps] [--noscripts][--notriggers] [--test] PACKAGE_NAME ...
[root@localhost Packages]# rpm -e zsh-html #此时无声胜有声。没有提示就是最好的提示,这样代表卸载成功
注意:在卸载程序包时,如果此程序被其他包所依赖,则将依赖于此包的所有包一并卸载,或者,使用�Cnodpes选项忽略依赖关系;但是,依赖于此程序的程序包可能无法正常运行。
⑤、RPM包校验
rpm {-V|--verify} [select-options] [verify-options]
[root@localhost Packages]# vim /etc/skel/.bash_logout [root@localhost Packages]# rpm -V bash S.5....T. c /etc/skel/.bash_logout #S.5....T. 每一位代表一个权限,请查看以下字段,通过查看权限位校验判断
S file Size differs(文件大小改变)
M Mode differs (includes permissions and file type)(权限改变)
5 digest (formerly MD5 sum) differs(MD5校验改变)
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(能力、功能不匹配)
也可以指定一下参数来忽略校验的选项。
--nodeps(不校验依赖关系)
--nofiles(不校验包文件的任何属性)
--noscripts(不校验脚本信息)
--nofiledigest (formerly --nomd5)
--nosize
--nouser
--nogroup
--nomtime
--nomode
--nordev
⑥、包来源合法性及完整性验正
包来源合法性验正及完整性验正:
完整性验正:SHA256
来源合法性验正:RSA
公钥加密:
对称加密:加密、解密使用同一密钥;
非对称加密:密钥是成对儿的,
public key: 公钥,公开所有人
secret key: 私钥, 不能公开
非对称加密机制
如果是通过官方或合法途径下载的镜像文件,镜像中都会提供使用非对称加密计算出来的一个密钥(RPM-GPG-KEY-CentOS-6),因为Packages中的包都是用(RPM-GPG-KEY-CentOS-6)密钥进行加密的,所以我们可以用(RPM-GPG-KEY-CentOS-6)来校验rpm包的完整性。
[root@localhost mnt]# rpm --import RPM-GPG-KEY-CentOS-6
在生产环境中安装不明来历的RPM包是极具风险的。所以安装有风险。以下提供可靠的RPM获取方法:
(1) 系统发版的光盘或官方的服务器;
CentOS镜像:
http://mirrors.aliyun.com
http://mirrors.sohu.com
http://mirrors.163.com
(2) 项目官方站点
(3) 第三方组织:
Fedora-EPEL
搜索引擎:
http://pkgs.org
http://rpmfind.net
http://rpm.pbone.net
(4) 自己制作
⑦、RPM包的数据库信息查询和管理
[root@localhost rpm]# pwd /var/lib/rpm [root@localhost rpm]# ls Basenames __db.004 Name Pubkeys Triggername Conflictname Dirnames Obsoletename Requirename __db.001 Filedigests Packages Requireversion __db.002 Group Providename Sha1header __db.003 Installtid Provideversion Sigmd5 #存储程序包名称及版本、依赖关系、功能说明、安装生成的各文件的文件路径及校验码信息 #Name(存放所有包名),Group(存放所有组),Conflictname(所有冲突关系),Requirename(包的依赖关系)等
当我们不小心误删除或此处文件有损坏的,就需要对数据库进行重建(读取每一个包的信息,然后进行重建)
rpm {--initdb|--rebuilddb}
initdb: 初始化
如果事先不存在数据库,则新建之;否则,不执行任何操作;
rebuilddb:重建
无论当前存在与否,直接重新创建数据库;