Linux程序包管理
涉及到的命令:rpm、yum、lftp
=====================================================================
API 应用编程接口
application programing interface
ABI 应用二进制接口
application binary interface
搞不懂二者关系,搜了一下感觉好像理解了点
api 是应用程序和操作系统之间的接口,凡是符合该api标准的应用程序都可以在支持该api的操作系统上编译通过。
abi 是二进制级别的接口,规定了二进制文件的格式、内容、装载/卸载程序的要求、函数调用时的参数传递规则、寄存器、堆栈的使用。
如果操作系统都支持该api,但是机器的体系结构不同即他们的abi不同,那么在一个机器上生成的二进制代码是不可以在另外一台机器上面运行成功的,可能因为函数调用的参数传递规则不同或者其他由abi定义的行为产生的差异性。
其实关键的是abi定义了运行时的兼容性问题,这个问题是api无法解决的。api所能解决的是静态状态下的兼容性问题。
程序的组成部分
编译之前:源代码
编译之后:
二进制程序
库文件
配置文件
帮助文档(手册、文档)
二进制程序路径一般都存放在:/bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin /opt/bin /opt/sbin
库文件:/lib /lib64 /usr/lib /usr/lib64 /usr/local/lib /usr/local/lib64 /opt/lib /opt/lib64
配置文件:/etc /etc/DIR /usr/local/etc /usr/local/conf
帮助文档:/usr/share/man /usr/share/doc /usr/local/share/man
注意:有些特殊的应用程序可能会将可执行程序文件放置于libexec目录
程序包管理器作用:
可以实现程序打包(特定格式)
对兼容程序包进行管理:
安装、卸载、升级、查询
注意:制作成二进制格式程序与平台有相关性,所以通常要制作各种流行平台兼容的版本
编译过程(以C为例)
源代码(文本)-- 预处理 -- 编译 -- 汇编 -- 链接
编译时,根据是否把调用的库文件直接打包进生成二进制程序文件,编译方式可分为两类:
动态链接:不将库文件打包进来,而是运行时装载它
静态链接:将被调用的库文件打包进来,将来运行时可以独立运行,无需外部库文件支持
程序包命名格式:
源代码:appname-version.tar.gz appname-version.tar.bz2 appname-version.xz (从左至右压缩比递增)
rpm包:appname-version-release.arch.rpm 程序包名 版本号 修正号 平台类型
常见的包管理器:
deb debian系列
rpm redhat package manager
rpm程序包的命名格式
appname-version-release.arch.rpm
version:(针对源程序)
major 主版本号
minor 次版本号
release发行号
release:rpm包制作的自身修订号
arch:使用平台,常见的有:
x86:i386 i486 i586 i686
x86_64:amd64 x86_64
powerpc:ppc
noarch:跟平台无关
分包机制:
核心包即主程序包:通常与源项目一致
子包(非核心功能包):命名为源项目名称后加上子包提供的功能描述组成
获取程序包的途径:
1、系统发行版光盘,或者官方站点
2、程序包的官方站点
3、第三方组织:epel
4、搜索引擎,如rpmfind.net rpm.pbone.net pkgs.org
建议:安装之前验证其合法性:来源合法和包的完整性
=====================================================================
centos上的rpm包管理:
安装、升级、卸载、查询、校验
rpm命令
安装:
rpm -i [install-option] package_file ...
-h hash,以#来表示安装进度,每个#代表2%
-v 详细信息 -vv 更详细 -vvv 更更详细
-test 测试安装,不执行真正的安装过程,而是仅报告依赖关系及冲突信息等
通常组合:
rpm -ivh package_File ...
程序包之间存在依赖关系:
由于是众多目的单一的小程序组成,结果程序包之间存在相关性
--nodeps 忽略依赖关系 副作用:能安装成功,但未必能成功运行
如:rpm -ivh --nodeps rmp_packages
--replacepkgs 覆盖原有,重新安装: 风险:原配置文件也会被覆盖
如: rpm -ivh ---replacepkgs rpm_packages
--force 强制安装:
升级:
-U:升级或安装,老版本在则升级,不存在则直接安装
-F:升级安装,老版本在则升级,不存在则不安装
常用组合:
rpm -Uvh rpm_packages
rpm -Fvh rpm_packages
降级:
--oldpackage 降级到旧版本
如:rpm -Uvh --oldpackage rm_packages
注意:一定不要对内核执行升级,Linux允许多内核共存,所以,可以直接安装不同版本的内核
如果程序包的配置文件在安装后进行修改,升级后,新版本的文件不会覆盖老版本的配置文件,而是把新版本的配置文件重命名保存(加后缀.rpmnew)
卸载:
移出已安装的安装包
-e
简单用法: rpm -e PACKAGE_NAME
--allmatches 如果一个程序包同时安装多个版本,则此选项一次性全部卸载
--nodeps 忽略依赖关系
--test 仅作测试卸载 (dry-run模式)
注意:如果程序包的配置文件安装后曾被修改,卸载时,此文件通常不会被删除,而是重命名留存(加后缀.rpmsave)
查询:
查询某包是否按照,以及检查安装的所有包,同时也可以查看某包的详细信息
rpm {-q|--query} [select-options] [query-options]
[select-options] :
1、查询某包是否安装
rpm -q package_name
2、查询已经安装所有的包
rpm -qa
3、查询某文件是由哪个包生成
rpm -qf /PATH/TO/SOMEWHERE
4、查询尚未安装的包文件的相关信息
-p
如:rpm -qpi package_file (package_file完整包名,尚未安装所以指定全名)
其他组合查询:-qpl -qpc -qpd
[query-options]:
1、查看某包的简要说明信息
rpm -qi package_name
2、查询某包安装后生成了哪些文件
rpm -ql package_name
3、查询某包安装完成后,生成的所有配置文件
rpm -qc package_name
4、查询包安装后的帮助文档
rpm -qd package_name
5、查看某包changelog信息,修订日志
rpm -q --changelog package_name
6、查询某包提供的capabilities
rpm -q --provides package_name
7、查看某包依赖的capabilities
rpm -q --requires package_name
8、查询某包安装或卸载时执行脚本
rpm -q --scripts package_name
脚本有四类:
preinstall 安装之前执行的脚本
postinstll 安装过程完成后执行的脚本
preuninstall 卸载之前,执行的脚本
postuninstall 卸载过程完成之后执行的脚本
校验:
-V 查询安装的包生成的文件是否发生改变
常见用法:
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
程序包来源合法性验证
来源合法
由信任的制作者提供
依赖于制作者的数字签名
内容合法
完整性校验,包未被进行二次修改
依赖于制作者提供的程序特征码,验证方法:安装者使用同样的特征码提取比对作者提供的
rpm --import RPM-GPG-KEY-Centos6 导入公钥(光盘中的包)
rpm -K package_file 验证
rpm -qa|grep gpg-pubkey 可以查到导入的公钥
rpm -e GPG-PUBKEY 如果想删除公钥可以进行卸载
rpm安装包后数据保存在数据库中的:
/var/lib/rpm/ rpm管理器数据库
重建数据库(如果损坏的情况下)
rpm {--initdb|--rebuilddb} [-v] [--dbpath DIRECTORY]
--inittab:初始化数据库,即数据库完全不存在时,可以新建之
--rebuilddb:无论当前数据库存在与否,都会直接重建此库
=====================================================================
Linux程序包管理--yum
yellowdog update modifier --> yum 能够自行解决依赖关系
yum repository数据包括两种:
数据:程序包
元数据:repodata
仓库指向的路径:repodata目录所在的父目录 (换句话说即指向的仓库路径目录中包含repodata目录)
createrepo命令创建元数据(后面有创建方法)
yum相对应于rpm来说
rpm是基础包管理器
yum则是rpm的前端工具,对rpm的一个补充
元数据缓存目录:/var/cache/yum
yum命令行工具:
配置文件:指向仓库的位置,以及相关的各种配置信息;每个yum命令行可以同时指向多个仓库,仓库间可以优先级等相关配置
有两部分组成:
1、/etc/yum.conf 为各仓库提供公共配置文件
2、各仓库的定义: /etc/yum.repos.d/*.repo
注意:文件以.repo结尾,每个repo配置文件中可以配置一个或多个仓库
各仓库配置解释: 位置:/etc/yum.repos.d/*.repo
[repositoryid]
对于当前系统的yum来讲,此repositoryid用于唯一表示此repository指向,因此必须唯一
name=描述信息
baseurl=url://path/to/repository/
指明repository的访问路径,通常为一个文件服务器上输出的某repository
url格式:
ftp服务:
ftp://server/path/to/repository
http服务
http://server/path/to/repository
nfs服务:不常用
nfs://server/path/to/repository
本地目录:
file:///path/to/repository
baseurl可以指向多个repository
enabled={0|1}
此仓库是否启用
gpgcheck={0|1}
是否对程序包做校验(优先级高于全局中的gpgcheck)
gpgkey=url://path/to/keyfile
指明个gpgkey文件路径
cost=#
指明当前repository的访问开销,默认是1000(越小优先级越高)
man yum.conf 中都可以找到以上描述
=====================================================================
yum命令的使用方法:
yum [options] [command] [package ...]
仓库管理
repolist 列出可用仓库
[all|enabled|disabled]
缓存管理:
clean [ packages | metadata | expire-cache | rpmdb | plugins | all ] 清理缓存
makecache 缓存创建;自动连接至每一个可用仓库,下载其元数据,将其创建为缓存
程序包查看:
list [all | glob_exp1 ] [glob_exp2] ...
list {available|updates|installed|extras|obsoletes} [glob_exp1]...
程序包安装:
install package1 ... 注意:只需要提供包名即可
/etc/yum.conf 中keepcache=1 表示保留缓存软件包(默认=0,软件安装后即删除)
如:yum install -y package1 ... 安装程序包自动回答为yes
注意:如果某包在仓库中有多个版本,默认会安装最新的,如果想按照指定版本: yum install PACKAGE-VERSION ...
重新安装:
reinstall 重新/覆盖安装
程序包升级:
update [package1] ...
upgrade,跟update一样
程序包降级
downgrade package1 [package2]
检查有哪些升级可用:
check-update
卸载
remove|erase package1 ...
注意:所有依赖于正在卸载程序包的包也一并卸载
查询
info PACKAGE ... 查看简要信息
search KEYWORD 在包名和summary信息中搜索指定的关键字(包名中含有或者描述信息中含有都会被列出)
provides | whatprovides /path/to/some/file 查找指定文件由哪个程序包生成
安装或升级本地程序包
localinstall rpmfile1 [rpmfile2] ... 用于安装仓库中并不存在的程序包
localupdate rpmfile1 [rpmfile2] ...
已经废弃,直接使用install 、update既可以安装仓库中的也可以安装本地的程序包
包组管理
grouplist 列出包组
groupinfo group1 [group2] ... 显示制定包组详情
groupinstall group1 [group2] ... 安装包组
groupremove group1 [group2] ... 卸载包组
groupupdate group1 [group2] ... 升级包组
也可以直接使用install、remove、update来管理包组,方法:
@group_name 如:yum install @"server platform development"
yum命令的可用选项:
-y 自动回答为yes
--disablerepo= 临时禁用某可用repository
--enablerepo= 临时启用指定的repository
--nogpgcheck 禁止包校验
yum有内置变量,用于保存当前平台的相关信息
1、$releasever 当前OS发行版的主版本号
例如:centos6.6 x86_64,主版本为6
2、$arch:平台
3、$basearch 基础平台
例如:i686 i586 i686已经i386的基础平台同位i386
4、$YUM0-$YUM9
例如:http://mirrors.aliyun.com/centos/$releasever/os/$basearch/
当前系统为centos6.7 x86_64则效果等同于:
http://mirrors.aliyun.com/centos/6.7/os/x86_64/
这么做的好处就是,可以写一个配置应用到同一主版本但不同发行版
自建yum仓库步骤:
1、基于发行版安装树,安装createrepo
yum install creatrepo
2、确定repository输出方式
本地输出:提供一个放置rpm包的本地路径
网络输出:提供一个文件服务器,配置好ftp服务或http服务
3、在准备好的目录中放置rpm包文件
4、对此目录运行createrepo命令即可
#createrepo /RPMFILE/PATH
一个非常好用的工具:lftp yum -y install lftp
[root@localhost yum.repos.d]# lftp http://mirrors.aliyun.com/centos/6.7/os/x86_64/
cd 成功, 当前目录=/centos/6.7/os/x86_64
lftp mirrors.aliyun.com:/centos/6.7/os/x86_64> ls
内容省略...
可以下载所有rpm包
mget *.rpm
练习:创建本地仓库,通过ftp或者http服务输出
服务器端操作:
1、安装httpd服务
#yum install -y httpd
2、关闭防火墙
#service iptables stop
3、下载实验用文件
#lftp mirrors.aliyun.com:/centos/6.7/os/x86_64/Packages
lftp mirrors.aliyun.com:/centos/6.7/os/x86_64/Packages> mget samba*
可以使用通配
3、在/var/www/html中新建目录,存放下载的rpm包
[root@localhost html]# mkdir localrepo
[root@localhost html]# mv ~/*.rpm localrepo/
4、安装createrepo工具并运行
#yum install -y createrepo
[root@localhost html]# createrepo localrepo/
Spawning worker 0 with 28 pkgs
Workers Finished
Gathering worker results
Saving Primary metadata
Saving file lists metadata
Saving other metadata
Generating sqlite DBs
Sqlite DBs complete
此时在localrepo目录中会出现repodata 目录
在另外一台测试客户端上:
1、移出原有yum文件
[root@localhost yum.repos.d]# mv CentOS-Base.repo CentOS-Base.repo.bak
2、新建配置文件,指向测试服务器
[root@localhost yum.repos.d]# cat local.test.repo
[repo-test]
name=172.20.1.33 local repo server
baseurl=http://172.20.1.33/localrepo/
enabled=1
gpgcheck=0
3、验证
[root@localhost yum.repos.d]# yum repolist
Loaded plugins: fastestmirror, refresh-packagekit, security
Loading mirror speeds from cached hostfile
repo id repo name status
repo-test 172.20.1.33 local repo server 28
repolist: 28
[root@localhost yum.repos.d]# yum list samba
Loaded plugins: fastestmirror, refresh-packagekit, security
Loading mirror speeds from cached hostfile
Available Packages
samba.x86_64 3.6.23-20.el6 repo-test