Linux程序包管理

软件包管理

功能:将编译好的程序的各组成文件打包成一个或几个程序包文件,为了方便的实现程序包的安装、升级、卸载、查询、校验、数据库维护。

APIApplication ProgramInterface应用程序接口;

ABIApplication BinaryInterface应用二进制接口;

Unix-likelinuxABI层次是相同的

linux程序包:ELF格式;

但是与Windows相差甚远

windows程序包:exemsi格式;

API层次兼容不一定ABI层次也兼容,有些操作系统对二进制格式识别格式(执行程序的格式),所以程序包即便是在源码层是兼容的,但一旦编译成功后,如果在linux上编译好的二进制格式程序,就不能在windows上运行,相反依然;

 

借助于库级别虚拟化可以实现跨平台兼容:

Linux上使用WinE能实现模拟成Windows运行环境;

Windows上使用cywin能实现模拟成Linux运行环境;

 

常见开发语言:

系统级开发:

c/c++:编出的程序有httpdnginxvsftpd

Go

应用级开发:

java/python/perl/ruby/php

java:运行java程序依赖于jvm虚拟机;tomcat,编出的程序有hadoopelkhbase

python:运行Python依赖于pvm虚拟机(Devops开发运维)解释性语言;编出的程序有openstackalphaGo

perl:运行依赖依赖于perl解释器(虚拟机)(perl

reby:运行依赖于ruby解释器(ruby

php:运行依赖于php解释器(php

 

程序包实际应用是以上两种开发揉合一起,使用多种编程语言分别实现各种功能,用服务器类程序,对性能要求非常高时使用系统级开发语言写系统核心,用应用级开发语言写一些辅助类的工具程序;

 

C/C++程序格式:

源代码:文本格式的程序代码;

编译依赖于编译开发环境:编译器、头文件、开发库(库文件也有两种格式:源代码、二进制格式);

二进制格式:文本格式的程序代码-->编译器-->二进制格式(二进制程序、程序自己的库文件、配置文件、帮助文件)

 

java/python程序格式:

源代码:要编译成能够在其虚拟机上(jvm/pvm)运行的二进制格式,而不是编译成直接在cpu上运行的二进制格式,虚拟机还要将其转换翻译成在cpu上运行的二进制格式;这种程序的源代码通常不止一个,因为编译时会出现依赖关系,关系到多个程序文件此时会用到项目构建工具;

二进制格式:

 

项目构建工具:

有了项目构建工具,在编译时不用指明编译文件的先后顺序,程序员事先在提供源代码时,已经用项目构建工具把编译文件先后顺序依赖关系都已经写好一个配置文档了,makemaven这种项目构建工具就可根这个配置文档自行完成编译操作;而这种项目构建工具也依赖开发环境才能构建;

开发环境:编译器、开发库

对于java来说有自己的开发环境,python也有自己的开发环境,对于这二者的开发环境指的是对应应用程序的虚拟机和虚拟机上所提供的编译器,这个编译器是编译javapython程序的,它们没有头文件而是用调用的库;

c/c++:程序项目管理工具make

java:程序项目管理工具maven                           

 

程序包管理器:

源代码-->目标二进制格式(包括二进制程序、程序自己的库文件、配置文件、帮助文件)(如果是c语言的就是编好的可直接运行的c代码)-->(把二进制程序、程序自己的库文件、配置文件、帮助文件)组织成为一个或有限几个“包”文件;

完成安装、升级、卸载、查询、校验;

 

程序包管理器:

把源代码转换为二进制格式(包括二进制程序、程序自己的库文件、配置文件、帮助文件)然后把这4种文件或更多的文件组织成一个或几个包文件的工具就是包管理器;

 

debiandptdebianpacket tool),dpgk(命令行工具),包后缀名为“.deb

redhatredhat packagemanager,rpm,包后缀名为“.rpm”;rpm is package manager

S.u.S.Erpm,但与redhat不兼容(文件路径不兼容,组织格式不兼容),包后缀名为“.rpm”,管理前端也叫rpm

 

Gentoo:使用ports机制安装管理的(freebsd风格);

ArchLinux:引入另外一种管理机制;

Ubuntu:就是debian的工具;           

 

源代码包命名格式:

name-VERSION.tar.gz

VERSIONmajor.minor.release

    主版本号.次版本号.发行号

major:代表重大的版本分支;

minor:代表在分支中的某个功能有了重大改变;

release:代表某段代码有了改变或修正了某个bug

 

rpm包命名格式:

name-VERSION-release.arch.rpm

VERSIONmajor.minor.release(源代码)

release.archrpm包的发行号改变;

有时为:release.os.arch:其中os代表是系统;

archarcheture平台架构,i386x64(amd64)ppcnoarch

例如:redis-3.0.2-1.centos7.x64.rpm

 

changelog:任何一个程序包的源代码版本发生演进时都会有这个文件,里面写明了新增功能、修复的bug等详细说明;

 

拆包:主包和支包

主包:name-VERSION-release.arch.rpm

支包(分包):name-function-VERSION-release.arch.rpm

function有很多种:devel(开发功能的分包),utils(工具程序分包),libs(库文件),尤其是php的包有很多分包(即为插件);

把一个包中的多种功能,拆分成N个组成部分;

一个程序包从源代码编译成二进制格式,源码包中有许多功能,对大多数用户来说,每种功能不一定都需要,比如,任何一类服务类应用程序都有两类组件,一类组件是运行的,一类组件是开发库,这个开发库提供程序的二次开发或增强性研发;当打包时一并把这两种组件都打包起来,如果不需要这些研发组件时,则这些组件就没有意义,还浪费了空间,因此,拆包就有意义了;      

 

依赖关系

前端工具:自动解决依赖关系;

yumrhel系列系统上rpm包管理器的前端工具;

apt-getapt-cache):deb包管理器的前端工具;

 

zyppersuserpm管理前端工具;

dnfFedora 22+系统上rpm包管理器的前端工具;

 

程序包管理器:

功能:将编译好的应用程序的各组成文件打包成一个或几个程序文件,从而更方便地实现程序包的安装、升级、卸载、和查询等管理操作;

 

1、程序包的组成清单(每个程序包都单独有自己的);

文件清单;

安装或卸载时运行的脚本;

2、数据库(公共);由包管理器管理;

存储程序包的名称和版本;

包之间的依赖关系;

各包的功能说明;

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

等等等;

 

程序包数据库存储路径:/var/lib/rpm

 

获取程序包的途径:

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

http://mirrors.aliyun.com

http://mirrors.sohu.com

http://mirrors.163.com

2)特定项目的官方站点

例如:

httpd.apache.org

www.zabbix.com

3)第三方组织制作的rpm

EPELredhat官方的社区组织所维护的除发行光盘之外制作的rmp

rpm包的搜索引擎:

http://pkgs.org

http://rpmfind.net

http://rpm.pbone.net

其它第三方组织;

4)自己动手制作rpm包,丰衣足食

 

注意:使用迅雷ptp下载工具,有可能不是从官方下载的,而是可能从已经下载者的地方下载的;

 

建议:检查rpm程序包合法性:

来源合法性;

程序包的完整性;

 

CentOS系统上的rpm命令管理程序包:

安装、升级、卸载、查询和校验、数据块维护;          

 

rpm命令:

rpm [OPTIONS] [PACKAGE_FILE]

安装:-i--install

升级:-U--update-F--freshen

卸载:-e--erase

查询:-q--query

校验:-V--verify

导入密钥:--import /PATH/TO/RPM-GPG-KEY

手动

数据库维护:--buiddb--initdb

每种功能还有很多复杂子选项;

 

rpm包安装:

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

 

常用格式:要有文件路径;

rpm -ivh PACKAGE_FILE ...

 

[install-options]安装选项:

   -h, --hashhash marks输出进度条,一共50#,每个#进度表示2%

   --test:测试安装,检查并报告依赖关系及冲突消息等,dry run模式;

   --nodeps:忽略依赖关系(安装后使用可能有问题),不建议;

   --replacepkgs:重新安装;

 

   --noscripts:不执行rpm包自带的四类脚本;

   --nopre:不执行rpm包自带的preinstall脚本;

   --nopost:不执行rpm包自带的postinstall脚本;

   --nopreun:不执行rpm包自带的preuninstall脚本;

   --nopostun:不执行rpm包自带的postuninstall脚本;

例如:

]# mount -r /dev/cdrom /media:虚拟机上的光盘连接后即可挂载;

]# rpm -ivh --test/media/Packages/zsh-5.0.2-7.el7.x86_64.rpm:测试安装;

]# rpm -ivh --replacepkgs /media/Packages/zsh-5.0.2-7.el7.x86_64.rpm

]# rpm -ivh/media/Packages/zsh-5.0.2-7.el7.x86_64.rpm

 

注意:rpm包可以自带脚本;

四类:--noscripts

preinstall:安装过程开始之前运行的脚本,标记为%pre--nopre

postinstall:安装过程完成之后运行的脚本,标记为%post--nopost

preuninstall:卸载过程真正开始执行之前运行的脚本,标记为%preun--nopreun

postuninstall:卸载过程完成之后运行的脚本,标记为%postun--nopostun

 

   --nosignature:不检查包签名信息,不检查来源合法性(有时,警告no key,但光盘上有key,可以手动导入);

   --nodigest:不检查包完整性信息,(不检查校验md5信息);

 

rpm包升级:

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

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

-U:表示升级或安装(发现旧版本则升级,没发现则直接安装);

-F:升级(只完成升级旧版本);

--nodeps

--test

--noscripts

 

常用格式:

rpm -Uvh PACKAGE_FILE ...

rpm -Fvh PACKAGE_FILE ...

 

--oldpackage:降级安装(新版程序包不兼容时,要回滚);

--force:强制升级;

例如:

]# rpm -Uvh /media/Packages/zsh-5.0.2-7.el7_1.2.x86_64.rpm:升级rpm包;

 

注意:

1)不要对内核做升级操作;Linux支持多内核版本并存,因此,要直接安装新版本内核;

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

 

rpm包卸载:

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

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

--nodeps:忽略依赖关系;

--test:测试卸载,dry run模式;

 

注意:卸载和查询时都无需程序文件路径,只需给出rpm程序包名即可;

安装和升级rpm程序包名需要rpm程序包文件完整路径;

 

rpm包查询:

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

-q

[select-options]:挑选查询哪些包;

PACKAGE_NAME:查询指定程序包是否安装及会显示详细版本信息;

-a--all:查询所有安装过的包;

-f FILE:查询指定文件(要写绝对路径)由哪个程序包安装生成的;

-g--group GROUP:查询指定包组中包含的程序包;

 

-p--packagepackage_file:对未安装的程序包查询(结合query-options选项),但要有rpm安装文件,否则无法查询;

 

--whatprovides CAPABILITY:查询指定的capability由哪个程序包提供(结合query-options选项);

--whatrequires CAPABILITY:程序指定的capability被哪个程序包依赖(结合query-options选项);

例如:

]# rpm -q zsh:查询指定rpm程序包;

]# rpm -qa:查询所有已安装的rpm程序包,可同grep搭配使用;

 

[query-options]:查询包的信息;

--changelog:查询指定rpm包的修改日志changelog

-i:查询指定rpm包相关的详细信息(版本、作者、功能描述、大小、所属包组...);

-l:查询指定rpm包安装后生成的所有文件列表;(二进制程序、配置文件、库文件、帮助文档)

-c:查看指定rpm程序的配置文件;

-d--docfiles:查看指定rpm程序包提供的文档;

--provides:查看指定rpm程序包提供所有的capability功能;

-R--requires:查询指定rpm包的依赖关系;

--scripts:查看rpm程序包自带的四类脚本程序片段(preinstallpostinstallpreuninstallpostuninstall);

例如:

]# rpm -q --changelog zsh:查询指定rpm包修改日志;

]# rpm -qi zsh:查询指定rpm包相关详细信息;

]# rpm -ql zsh:查询指定rpm包生成的所有文件列表;

]# rpm -qc zsh:查询指定rpm包所包含的配置文件;

]# rpm -qd zsh:查询指定rpm包提供的文档;

]# rpm -q --provides bash:查询指定rpm包提供的所有能力;

]# rpm -q --whatprovides bash:查询指定rpm包由哪个程序包提供;

]# rpm -q --whatprovides 'config(bash)'

]# rpm -q --whatrequires bash:查询指定rpm包被哪个程序包所依赖;

]# rpm -q -R zsh:查询指定rpm包的依赖关系;

]# rpm -q --scripts zsh:查询指定rpm包自带的四类脚本程序代码;

 

查询未安装的rpm包的相关信息,但必须有rpmb的安装文件才能查询;   

]# rpm -qpl/media/Packages/zsh-5.0.2-7.el7.x86_64.rpm:查询未安装的rpm包安装后生成的所有文件列表;   

]# rpm -qpi/media/Packages/zsh-5.0.2-7.el7.x86_64.rpm:查询未安装的rpm包相关详细信息;

]# rpm -qpc/media/Packages/zsh-5.0.2-7.el7.x86_64.rpm:查询未安装的rpm包配置文件;

]# rpm -qpd/media/Packages/zsh-5.0.2-7.el7.x86_64.rpm:查询未安装的rpm包提供的文档;

]# rpm -qp --scripts/media/Packages/zsh-5.0.2-7.el7.x86_64.rpm:查询未安装的rpm包自带的四类脚本程序片段;

 

rpm包校验:

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

--nodeps:不校验依赖关系;

--nodigest:不检查包完整性;

--nofiles:不校验文件属性是否发生改变;

--nosignature:不检查包或头部签名;

例如:

]# rpm -V --nofiles zsh

 

校验结果各位置的代表意思(9位):

 

例如:S.5....T.

 

S file Size differs:大小改变;

M Mode differs (includes permissions andfile 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:能力发生改变;

 

包来源合法性验证和完整性验证:

来源合法性验证:

完整性验证:

 

rpm包来源合法性验证和完整性验证,导入密钥:

ISO镜像光盘为例,将镜像文件导入虚拟机光驱,并开启连接;

挂载后,查看文件:密钥文件

RPM-GPG-KEY-CentOS-7       

对于CentOS发行版来说:

获取并导入信任的包制作者的密钥(公钥):

导入密钥文件:

例如:

]# rpm --import /media/RPM-GPG-KEY-CentOS-7

对于光盘会自带密钥,再安装rpm包程序时,不会显示no key了。

 

验证:

1)安装此组织的签名的程序时,会自动执行验证(导入密钥文件后,再安装rpm包时会自动验证);

2)手动验证:rpm -K PACKAGE_FILE

例如:

]# rpm -K /media/Packages/zsh-5.0.2-7.el7.x86_64.rpm

 

数字签名(单向加密):采用非对称加密,一对秘钥(公钥,私钥),用私钥加密对应数据的特征码(加密程序包的校验码),用公钥解密;从而实现来源合法性验证和完整性验证的目的;

 

加密:

第一步:程序包制作者首先用单向加密,计算出程序包的特征码(校验码)出来,是定长输出,

第二步:然后再用自己的私钥来加密这个特征码,这叫数字签名,并且把加密后的特征码附加在程序包后面;

 

解密:

第一步:首先用程序包制作者的公钥解密特征码后,如果能解密则认为完成来源合法性验证;

第二步:然后,用同样的单向加密算法对程序包进行单向加密计算出一个特征码,用计算得出的特征码与解密的特征码比较,相同则完整性校验成功,不同则完整性校验失败;

 

注意:要确保获得安全的公钥!

 

rpm包数据库维护:

 

rpm包数据库位置:/var/lib/rpm

查询操作(包括安装、升级、卸载、查询):都是通过此处的数据库进行的;

 

获取重建帮助:

CentOS6man rpm

CentOS7man rpmdb

重建:

rpm {--initdb|--rebuilddb} [--dbpathDIRECTORY] [--root DIRECTORY]

 

--initdb:初始化数据库,当前无任何数据库可实现初始化创建一个新的,当前有时不执行任何操作;如果事先不存在数据库,则新建,否则,不执行任何操作;

 

--rebuilddb:重新构建,通过读取当前系统上所有已经安装过的程序包进行重新创建;无论当前是否存在,直接重新创建数据库;