程序包管理
软件包管理
一、c语言程序的构建过程
1.程序源代码 --> 预处理 --> 编译 --> 汇编 --> 链接--> 可执行程序
- 开放源码:就是程序码,文本格式的源代码,写给人类看的程序语言,但机器并不认识,所以无法执行;
- 编译器:将程序码转译成为机器看的懂得语言,就类似翻译者的角色,生成二进制文件;
- 链接:在Linux上使用ld工具,将o文件和所需的库文件链接起来组成一个可正常工作的可执行程序。链接了库文件之后就可以发起一些系统调用。
- 静态编译:.a
- 把程序对应的依赖库复制一份到包
- libxxx.a
- 嵌入程序包
- 升级难,需重新编译
- 占用较多空间,迁移容易
- 动态编译:.so
- 只把依赖加做一个动态链接
- libxxx.so
- “连接指向”
- 占用较少空间,升级方便
- 指针指向,软链接
- 静态编译:.a
- 可执行文件:经过编译器变成二进制程序后,机器看的懂所以可以执行的文件。
2.二进制程序的组成部分:二进制文件、库文件、配置文件、帮助文件
查看二进制程序所依赖的库文件:
ldd /PATH/TO/BINARY_FILE
3.包命名规则:
源代码:name-VERSION.tar.gz | bz2 | xz;
VERSION: major.minor.release
rpm包:name-VERSION-release.arch.rpm
例:bash-4.2.46-19.el7.x86_64.rpm
VERSION: major.minor.release
release:release.OS
常见的arch:
x86: i386, i486, i586, i686
x86_64: x64, x86_64, amd64
powerpc: ppc
跟平台无关:noarch
一般,源码都是打包压缩过的文件,其通常以“.gz”、“.bz2”、“.xz”结尾,源码包中包含了源码,还包含了一些有助于制作二进制rpm的文件;rpm包一般以“rpm”结尾,都是已经编译完成的,安装rpm包的过程实际上就是将包中的文件复制到Linux上,有可能还会在复制文件的前后执行一些命令,如创建一个必要的用户,删除非必要文件等。
4.包管理器:
- debian:deb文件, dpkg包管理器
- redhat: rpm文件, rpm包管理器
- rpm: Redhat Package Manager
- RPM Package Manager
5.包的分类与拆包
Application-VERSION-ARCH.rpm: 主包
Application-devel-VERSION-ARCH.rpm 开发子包
Application-utils-VERSION-ARHC.rpm 其它子包
Application-libs-VERSION-ARHC.rpm 其它子包
注意:包之间可能存在依赖关系,甚至循环关系;
解决依赖包管理工具:
yum:rpm包管理器的前端工具
apt-get:deb包管理器前端工具
zypper: suse上的rpm前端管理工具
dnf: Fedora 18+ rpm包管理器前端管理工具
6.获取程序包的途径:
(1) 系统发版的光盘或官方的服务器;
CentOS镜像:
https://www.centos.org/download/
http://mirrors.aliyun.com
http://mirrors.sohu.com
http://mirrors.163.com
(2) 项目官方站点
(3) 第三方组织:
Fedora-EPEL:
Extra Packages for Enterprise Linux
Rpmforge:RHEL推荐,包很全
搜索引擎:
http://pkgs.org
http://rpmfind.net
http://rpm.pbone.net
https://sourceforge.net/
注意:第三方包要检查其合法性、完整性!!
7.库文件
一些查看命令:
ldd /PATH/TO/BINARY_FILE # 查看二进制程序所依赖的库文件
ldconfig -p # 显示本机已经缓存的所有可用库文件名及文件路径映射关系
8.程序的配置文件和缓存文件:
配置文件:
/etc/ld.so.conf 全部放到一个文件中,或
/etc/ld.so.conf.d/*.conf 此文件目录下.cong结尾的文件,方便一个程序写一个配置文件
缓存文件:
/etc/ld.so.cache
二、rpm管理器
1.程序包管理器:
功能:将编译好的应用程序的各组成文件打包一个或几个程序包文件,从而方便快捷地实现程序包的安装、卸载、查询、升级和校验等管理操作
包文件组成 (每个包独有)
RPM包内的文件
RPM的元数据,如名称,版本,依赖性,描述等
安装或卸载时运行的脚本
数据库(公共):/var/lib/rpm
程序包名称及版本
依赖关系
功能说明
包安装后生成的各文件路径及校验码信息
ll /var/lib/rpm/
total 75612
-rw-r--r--. 1 root root 5521408 Oct 23 18:48 Basenames
-rw-r--r--. 1 root root 12288 Oct 23 18:47 Conflictname
-rw-r--r--. 1 root root 73728 Dec 4 11:57 __db.001
-rw-r--r--. 1 root root 229376 Dec 4 11:57 __db.002
-rw-r--r--. 1 root root 1318912 Dec 4 11:57 __db.003
-rw-r--r--. 1 root root 753664 Dec 4 11:57 __db.004
# 这个rpm包数据库文件夹中包含着现有已经安装的包的各种信息,包括安装版本,安装时间、升级时间、卸载时间等等非常重要,最好备份
2.rpm命令的使用
CentOS系统上使用rpm命令管理程序包:
安装、卸载、升级、查询、校验、数据库维护。
2.1 安装
rpm {-i|--install} [install-options] PACKAGE_FILE…
# option
-v: verbose
-vv:
-h: 以#显示程序包管理执行进度
rpm -ivh PACKAGE_FILE ... # 安装某程序包
[install-options]
--test: 测试安装,但不真正执行安装,即dry run模式
--nodeps:忽略依赖关系
--replacepkgs | replacefiles # 对于已经安装过的包,如果不经过卸载,只是删除其一些文件,就会导致这个程序无法使用,我们再重新安装这个程序包时,会显示此包已经安装,是因为在/var/lib/rpm这个文件中有该程序的安装记录。所以这种情况下要想重新安装这个程序包就需要rpm -ivh --replacepkgs 这个选项!
--nosignature: 不检查来源合法性
--nodigest:不检查包完整性
--noscripts:不执行程序包脚本
%pre: 安装前脚本; --nopre
%post: 安装后脚本; --nopost
%preun: 卸载前脚本; --nopreun
%postun: 卸载后脚本; --nopostun
注意:
我们在rpm安装时截图中红框位置显示nokey是因为我们没有导入RPM-GPG-KEY-CentOS-7这个检查工具来检查其合法性,导入后即可显示
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
(rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6 (centos6)
)导入公钥即可检查,这样在安装来源合法的程序包时就不在显示nokey。
2.2 升级
rpm {-U|--upgrade} [install-options] PACKAGE_FILE...
upgrade # 安装有旧版程序包,则“升级”;如果不存在旧版程序包,则“安装”
rpm {-F|--freshen} [install-options] PACKAGE_FILE...
freshen # 安装有旧版程序包,则“升级”;如果不存在旧版程序包,则不执行升级操作
rpm -Uvh PACKAGE_FILE ...
rpm -Fvh PACKAGE_FILE ...
--oldpackage:降级
--force: 强制安装
注意:
(1) 不要对内核做升级操作;Linux支持多内核版本并存,因此,对直接安装新版本内核;
(2) 如果原程序包的配置文件安装后曾被修改,升级时,新版本的提供的同一个配置文件并不会直接覆盖老版本的配置文件,而把新版本的文件重命名(FILENAME.rpmnew)后保留。
2.3查询
rpm {-q|--query} [select-options] [query-options]
[select-options]
-a: 所有包
-f: 查看指定的文件由哪个程序包安装生成
-p rpmfile:针对尚未安装的程序包文件做查询操作
--whatprovides CAPABILITY:查询指定的CAPABILITY由哪个包所提供
--whatrequires CAPABILITY:查询指定的CAPABILITY被哪个包所依赖
[query-options]
--changelog:查询rpm包的changelog
-c: 查询程序的配置文件
-d: 查询程序的文档
-i: information
-l: 查看指定的程序包安装后生成的所有文件
--scripts:程序包自带的脚本
--provides: 列出指定程序包所提供的CAPABILITY
-R: 查询指定的程序包所依赖的CAPABILITY
rpm2cpio 包文件|cpio –itv 预览包内文件
rpm2cpio 包文件|cpio –id “*.conf” 释放包内文件
2.4 卸载
rpm {-e|--erase} [--allmatches] [--nodeps] [--noscripts] [--notriggers] [--test] PACKAGE_NAME ...
注意:由于我们在安装程序包是会同时安装许多依赖文件,而这种卸载方法只是卸载程序本身,并不同时将依赖文件卸载,所以要想完整卸载的话需要用yum
yum history # 查看历史记录,找到是第几部的操作
yum history undo # # 表示对历史操作中的第#想进行反操作
2.5 包校验
rpm {-V|--verify} [select-options] [verify-options]
# option
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 -K|checksig rpmfile 检查包的完整性和签名
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
CentOS 7发行版光盘提供:RPM-GPG-KEY-CentOS-7
rpm -qa “gpg-pubkey*”
三、yum
yum工具通过仓库的方式简化rpm包的管理。它从仓库中搜索相关的软件包,并自动下载和解决软件包的依赖性,非常方便。yum底层依赖rpm,如果把rpm卸载,那么yum也不能用了。
老王说:
利用yum的主要问题:
(1)配置文件格式语法错误;
(2)缓存问题
yum客户端配置文件:
/etc/yum.conf # 为所有仓库提供公共配置
/etc/yum.repos.d/*.repo # 为仓库的指向提供配置
[root@CentOS7 ~]#cat /etc/yum.conf
[main]
cachedir=/var/cache/yum/$basearch/$releasever # 缓存文件夹路径
$$basearch # cpu架构,X86_64等
$releasever # 系统版本
keepcache=0 # 0代表不缓存rpm包,下载安装后默认删除;1为缓存rpm安装包
debuglevel=2 #
logfile=/var/log/yum.log # yum安装的日志文件
exactarch=1 #
obsoletes=1
gpgcheck=1 # 默认1代表安装包的完整性合法性为nokey是直接拒绝安装
plugins=1
installonly_limit=5
bugtracker_url=http://bugs.centos.org/set_project.php?project_id=23&ref=http://bugs.centos.org/bug_report_page.php?category=yum
distroverpkg=centos-release
# PUT YOUR REPOS HERE OR IN separate files named file.repo
# in /etc/yum.repos.d
自己搭建一个yum配置文件
vim /etc/yum.repo.d/base.repo # 两个必须:1必须在/etc/yum.repo.d/这个文件夹下;2.文件名必须以.repo结尾;一般习惯将光盘建的yum库命名为base
[base] # 不允许有空格
name=cdrom
baseurl=file:///mnt/cdrom/ # 一般是repodata的父目录,文件路径不允许有空格,支持http:// https:// ftp:// file://
# 此地址可以添加多个地址,在多个地址的情况下,可以将全部地址保存在一个文本文件中,而此处的baseuer换成 mirrorlist=file:// 文件路径
gpgcheck=0 # 0默认为不进行gpgcheck检查完整性
以上这些是必须项,
-----------------------------------------------------
还可以添加:
gpgkey=file:///mnt/cdrom/RPM-GPG-KEY-CentOS-7 # 直接将光盘中的公钥导入,也可以换成
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 # 直接导入配置文件中的公钥;此项不加的话,gpgcheck=0;
enabled=0 # 默认为1,0为临时禁用该仓库
failovermethod={roundrobin|priority} # 这个是在baseurl包含多个地址的情况下使用
roundrobin # 意为随机挑选,默认值
priority # 按顺序访问
cost=1000 # 存在多个仓库的情况下,越少优先值越高
也可以通过命令直接生成该配置文件:
yum-config-manager --add-repo=BASEURL # 即自动生成该网址的repo配置文件
yum-config-manager --disable “仓库名" # 禁用仓库
yum-config-manager --enable “仓库名” # 启用仓库
搭建完yum配置文件即可使用yum安装了。
[aliyunepel]
name=aliyun-epel
baseurl=https://mirrors.aliyun.com/epel/7/x86_64/
gpgcheck=0
# 这样就又搭建了一个阿里云的epel的yum库
yum的其他一些命令
yum install PACKAGES # yum安装程序包
yum reinstall package1 [package2] [...] # 重新安装
yum remove PACKAGES # yum卸载程序包
yum remove | erase package1 [package2] [...]
yum repolist # 可查看搭建的yum库有多少个安装包。
yum repolist all # 显示所有的仓库情况
yum clean # 清除yum缓存
cat /var/log/yum.log # 查看yum安装报的日志文件,包括安装、卸载、更新等
yum list # 显示所有库中所有的包,前带@说明已经安装
yum list *ftp* # 支持文件名通配符,列出包含ftp的程序包
yum list [all | glob_exp1] [glob_exp2] [...] # 列出包,支持文件名通配符
yum list {available|installed|updates} [glob_exp1] # 列出可用的、可安装的、能升级的
yum update [package1] [package2] [...] # 升级,一般不建议升级
yum downgrade package1 [package2] [...] # 降级
yum check-update # 检查可用升级
yum info [...] # 查询包信息
yum provides | whatprovides feature1 [feature2] # 查看指定的特性(可以是某文件)是由哪个程序包所提供
yum clean [ packages | metadata | expire-cache | rpmdb | plugins | all ] # 清除/var/cache/yum/$basearch/$releasever缓存,清楚类型指定,all为所有
yum makecache # 构建缓存
yum search string1 [string2] [...] # 以指定的关键字搜索程序包名及summary信息
yum deplist package1 [package2] [...] # 查看指定包所依赖的capabilities
如图所示,两个yum库分别有多少个包均有显示
注意:yum不允许同时在多个终端同时安装
yum的repo配置文件中可用的变量:
$releasever: 当前OS的发行版的主版本号
$arch: 平台,i386,i486,i586,x86_64等
$basearch:基础平台;i386, x86_64
$YUM0-$YUM9:自定义变量
比如:
实例:(针对不同版本的系统)
http://server/centos/$releasever/$basearch/
http://server/centos/7/x86_64
http://server/centos/6/i384
对于repo文件我们也可以参考阿里云,
http://mirrors.aliyun.com/repo/
将其的配置格式直接作为我们自己的配置。
可通过:
wget url....下载配置文件至当前目录
查看yum历史事务:
yum history [info|list| packages-list| packages-info| summary | addon-info | redo | undo | rollback | new|sync| stats]
yum history # 查看历史记录
yum history info 6 # 查看yum历史记录第六条的详细信息
yum history undo 6 # 反向操作yum历史记录第六条的操作
利用yum安装rpg包:
yum install rpmfile1 [rpmfile2] [...] #
yum update rpmfile1 [rpmfile2] [...]
利用yum安装包组
yum groupinstall group1 [group2] [...]
yum groupupdate group1 [group2] [...]
yum grouplist [hidden] [groupwildcard] [...]
yum groupremove group1 [group2] [...]
yum groupinfo group1 [...]
yum grouplist # 查看包组列表
yum的一些命令选项:
yum的命令行选项:
--nogpgcheck:禁止进行gpg check
-y: 自动回答为“yes”
-q:静默模式
yum -y -q :需要分开写
--disablerepo=repoidglob:临时禁用此处指定的repo,repo配置文件中[]中的名字
--enablerepo=repoidglob:临时启用此处指定的repo
--noplugins:禁用所有插件
补充:
systemctl stop firewalld # 关闭防火墙
systemctl disable firewalld # 关闭开机自动启动防火墙
四、实验
实验1:
当知道是哪个库文件被删除(以删除/lib64/libc.so.6这个库文件为例),导致无法使用命令或系统不能使用时,这么修复:(以CentOS 7为例)
第一步:重启,从光盘开机,有的系统是开机f2修改,有的是f12,还有的是Esc键;
第二步:进入此界面,选择第三项Troubleshooting进入
再选择第二项rescure centos system ,进入救援模式;
再选择第一项continue进入bash shell界面。
通过df命令可以看到,根目录已经变成/mnt/sysimage;所以,我们在cp丢失的文件时要使用相对路径。
!!注意:libc.so.6 这个文件是个软链接,也就是说我们实验时cp到data目录下的库文件是个软链接,并不是真正的库文件,所以这样的话我们再重新创建个软链接即可。
ln -s libc-2.17.so libc.so.6
(注意,此处要切换至/mnt/sysimage/lib64下,使用相对路径进行创建软链接)
重启,正常!(注意,将从光盘启动改回从硬盘启动)
实验2:
像centos6那样,可以直接依靠/misc/cd 打开光盘文件
第一步:yum install autufs
这个包
第二步:systemctl start autofs
打开autofs服务
(注意:centos特有的,可以通过rpm -ql autofs 查看到其有个服务文件,所以需要命令打开它)
第三步:再通过systemctl enable autofs
命令让其开机自动启动服务
此时,centos7 也可以通过 cd /misc/cd 切换至光盘
实验3:
用centos7的安装光盘为centos6的客户机搭建一个yum库
第一步:安装并开启httpd
yum install httpd # 安装httpd
systemctl stop firewalld # 关闭防火墙
systemctl disable filewalld # 关闭自动启动防火墙
打开浏览器,在地址栏输入ip地址,看是否可以连接,如图所示已经连接成功
第二步:
cd /var/www/html/ # 切换至该文件夹
mkdir -p epel/{6,7}/x86_64/ # 模仿阿里云的epel网址格式分别创建6和7两个文件夹
第三步:挂载光盘
mount /dev/sr0 /var/www/html/epel/7/x86_64/ # 挂载硬盘至指定目录,如果是想在centos7上使用这个库就用7的文件夹
mount /dev/sr0 /var/www/html/epel/6/x86_64/ # 如果是想在centos6上使用这个库就用6的文件夹
如图所示,已经可以在浏览器中查看到我们挂载的光盘的内容
第四步:后面的就修改 /etc/yum.con.d/ 下的配置文件按正常操作即可。