我们日常在使用Windows的时候,如果要安装某个软件,最简单的方法就是在程序包的官网直接下载软件包到本地,一般是以.exe或者.msi格式的文件,然后一直下一步下一步就能安装成功了,但是在使用linux的操作系统的时候也许不是这么的友好,即使现在有的linux发行版也可以通过简单的搜索点击安装来实现软件包的安装,但这并不一种很好的安装方法,因为你必须安装桌面环境,消耗和占用一定的内存资源,除非只是你日常使用。本次博客就如何使用rpm命令来实现centos上的软件包的安装与管理,rpm也许不是最明智的选择,但是在学习yum之前,我们还是先来看一下rpm吧!
rpm包的组成和获取路径
程序包,简单的来说就是将源代码通过编译器编译成二进制格式的程序,然后将二进制程序、库文件、配置文件和帮助文件组成为一个或者有限几个“包”文件。
在不同的linux发行版上,提供的程序包的管理器并不是都相同的,比如debian系的使用的包管理器是dpkg(包文件后缀名.deb),在rehat和SUSE系使用都是rpm( rpm is package manager),centos作为redhat的分支,自然使用的是rpm了,而这些包文件的后缀名就是.rpm。
来看一下这些文件吧!(这里使用grep显示了包文件名中只含有yum的包名)
rpm包命名的格式:
先来看一下源代码的命令格式,一般程序的官网会提供程序的源代码文件,你可以通过源代码编译安装:
zabbix-3.4.1.tar.gz
version:major.minor.release
major:主版本号,源码发生巨大的改变,则会改变;
minor:次版本号,源码发生了较大的改变,则会改变;
release:发行号,当修复了很小的bug的时候,则会改变。
再来看一下包的命令格式:
yum-3.4.3-150.el7.centos.noarch.rpm
格式:name-VERSION-release.arch.rpm
VERSION为源码的版本号;
releas为rpm包的发行号;
arch为包可以运行的平台,如i386,x64(amd64),ppc,noarch(说明可以在不同的平台上安装)等。
如这里的yum-3.4.3-150.el7.centos.noarch.rpm,yum为包名,3.4.3为源码版本,el7.centos代表centos7,noarch说明你可以在不同的平台上使用它。
从上面的图上我们可以看到,除了一个以yum为名字的包以外还有很多其他包含yum的包,当我们安装了这些包之后,可以为yum提供更多的额外的功能。
包文件的组成(每个包都是单独实现的):
rpm包内的文件;
rpm的元数据,依赖关系,描述等;
安装和卸载时候运行的脚本。
公共的数据库(/var/lib/rpm):
程序包的名称和版本;
依赖关系;
功能说明;
安装生成的各文件的文件路径及校验码信息。
依赖关系:
做为linux重要的哲学思想之一,单一程序的组合起来完成复杂的任务,rpm包之间也是这样的,如果想要实现一个复制的功能,可能需要多个rpm包之间相互依赖才能实现,例如,你装A软件包,可能依赖于B包,那么你就需要安装B包,你安装B包,可能又要依赖于C包,所以你在安装A包的时候,就需要同时报B包和C包都装上去。这样一个一个安装固然很浪费时间,所以linux也提供了一些前端工具来自动解决依赖关系:
yum:rhel系列系统上rpm包管理器的前段工具
apt-get:deb包管理器的前端工具
zypper:suse的rpm管理器前端工具
dnf:Fedora 22+系统上的rpm包管理器的前端工具。
获取程序包的途径
(1)系统发行版的光盘或官方的文件服务器:
(3)第三方组织
(4) 毛爷爷说过:自己动手,丰衣足食!
rpm命令
centos上使用rpm命令来实现程序包的安装、升级、卸载、查询、校验和数据库的维护。
一、安装
rpm {-i|--install} [install-options] PACKAGE_FILE ... 选项: -i,--install:安装包 -v:verbose,详细信息 -vv:更详细的输出 [install-options]: -h:hash marks输出进度条,每个#表示2%的进度 --test:测试安装,但是并没有安装,检查并报告依赖关系及冲突消息等 --nodeps:忽略依赖关系安装,不建议 --replacepkgs:重新安装 --nosignature:不检查包的签名信息,不检查来源合法性 --nodigest:不检查包完整性信息 注意:rpm可以自带脚本 总共有4类脚本: preinstall:安装过程开始之前运行的脚本,%pre postinstall:安装过程完成之后运行的脚本,%post preuninstall:卸载过程真正开始执行之前运行的脚本,%preun postuninstall:卸载过程完成之后运行的脚本,%postun --noscripts:不执行这四种脚本 --noper:不执行preinstall脚本 --nopost:不执行postinstall脚本 --nopreun:不执行preuninstall脚本 --nopostun:不执行postuninstall脚本
下面我们来举一些例子吧!
1.安装zsh,并显示详细信息和进度条:
[root@localhost Packages]# rpm -ivh zsh-5.0.2-25.el7.x86_64.rpm #最常用的组合 -ivh Preparing... ################################# [100%] Updating / installing... 1:zsh-5.0.2-25.el7 ################################# [100%] [root@localhost Packages]#
2.修改zsh的配置文件,再执行重新安装:
[root@localhost Packages]# rpm -i --replacepkgs zsh-5.0.2-25.el7.x86_64.rpm
说明重新安装并不会覆盖原有的配置文件。
3.忽略依赖性安装
[root@localhost Packages]# rpm -i xterm-295-3.el7.x86_64.rpm #提示需要以下的capability才能安装成功 error: Failed dependencies: libICE.so.6()(64bit) is needed by xterm-295-3.el7.x86_64 libXaw.so.7()(64bit) is needed by xterm-295-3.el7.x86_64 libXmu.so.6()(64bit) is needed by xterm-295-3.el7.x86_64 libXpm.so.4()(64bit) is needed by xterm-295-3.el7.x86_64 libXt.so.6()(64bit) is needed by xterm-295-3.el7.x86_64 [root@localhost Packages]# rpm -i --nodeps xterm-295-3.el7.x86_64.rpm #忽略依赖性关系安装
二、升级
rpm {-U|--upgrade} [install-options] PACKAGE_FILE ... rpm {-F|--freshen} [install-options] PACKAGE_FILE ... 选项: -U:升级或安装 -F:升级 [install-options]:支持安装不部分的install-options --oldpackage:降级 --force:强制升级 注意:(1)不要对内核做升级操作,linux支持多内核版本并存,因此直接安装新版本的内核 (2)如果某原程序包的配置文件安装后曾被修改,升级时,新版本的程序提供的同一个配置文件不会覆盖原有的配置文件。
三、卸载
rpm {-e|--erase} [--allmatches] [--nodeps] [--noscripts] [--test] PACKAGE_NAME ... 选项: -e:卸载 --allmatches:卸载所有pip指定名称的程序包的各个版本 --nodeps:忽略依赖关系 --test:测试卸载,dry run模式
举例:
卸载zsh,卸载后被修改的配置文件会被保存为.rpmsave的文件。
[root@localhost Packages]# rpm -e zsh warning: /etc/zshrc saved as /etc/zshrc.rpmsave [root@localhost Packages]# [root@localhost Packages]# rpm -i zsh-5.0.2-25.el7.x86_64.rpm [root@localhost Packages]# [root@localhost Packages]# vim /etc/zshrc zshrc zshrc.rpmsave
四、查询
rpm {-q|--query} [select-options] [query-options] -q:查询操作 [select-options]: PACKGE_NAME:查询指定的程序包是否已经按照及版本 -a,--all:查询所有已经按照过得包 -f FILE:查询指定的文件是由哪个程序包安装生成的 -p,--packges PACKAGE_FILE:用户实现对未安装的程序包执行查询操作 --whatprovides CAPABILITY:查询指定的CAPABILITY由哪个程序包提供 --whatrequires CAPABILITY:查询指定的CAPABILITY被哪个包所依赖 [query-options] --changelog:查询rpm包的changelog -l,--list:程序包安装生成的所有文件列表 -i,--info:程序包相关的信息,版本、大小、所属包组等 -c,--configfiles:查询指定的程序包提供的配置文件 -d,--docfiles:查询指定的程序包提供的文档 --provides:查询指定程序包提供的所有的CAPABILITY -R,--requires:查询指定的程序包的依赖关系 --scripts:查看程序包自带的脚本片段
举例:
[root@localhost Packages]# rpm -q zsh #查询zsh是否被安装 zsh-5.0.2-25.el7.x86_64 [root@localhost Packages]# rpm -qf /etc/zshrc #查询/etc/zshrc是由哪个包安装生成的 zsh-5.0.2-25.el7.x86_64 [root@localhost Packages]# rpm -q --changelog zsh #查询zsh的修改日志 * Thu Jul 14 2016 Kamil Dudka <kdudka@redhat.com> - 5.0.2-25 - improve use of new command substitution in completion (#1356388) * Fri Jun 10 2016 Kamil Dudka <kdudka@redhat.com> - 5.0.2-24 - fix off-by-one error in completion utility cache code (#1344599) * Mon May 23 2016 Kamil Dudka <kdudka@redhat.com> - 5.0.2-23 - fix parse error on a script with unescaped exclamation mark (#1338689) ......(略) [root@localhost Packages]# rpm -ql zsh #查询安装zsh会生成的文件列表 /bin/zsh /etc/skel/.zshrc /etc/zlogin /etc/zlogout /etc/zprofile /etc/zshenv /etc/zshrc /usr/lib64/zsh /usr/lib64/zsh/5.0.2 ......(略) [root@localhost Packages]# rpm -qc zsh #查询安装zsh所生成的配置文件 /etc/skel/.zshrc /etc/zlogin /etc/zlogout /etc/zprofile /etc/zshenv /etc/zshrc [root@localhost Packages]# rpm -qd zsh #查询安装zsh所生成的文档信息 /usr/share/doc/zsh-5.0.2/BUGS /usr/share/doc/zsh-5.0.2/CONTRIBUTORS /usr/share/doc/zsh-5.0.2/FAQ /usr/share/doc/zsh-5.0.2/FEATURES /usr/share/doc/zsh-5.0.2/LICENCE /usr/share/doc/zsh-5.0.2/MACHINES /usr/share/doc/zsh-5.0.2/NEWS ......(略) [root@localhost Packages]# rpm -q --provides zsh #查询zsh所提供的CAPABILITY config(zsh) = 5.0.2-25.el7 zsh = 5.0.2-25.el7 zsh(x86-64) = 5.0.2-25.el7 [root@localhost Packages]# rpm -qR zsh #查询zsh所依赖的CAPABILITY /bin/sh /bin/sh /bin/sh /bin/sh /bin/zsh /sbin/install-info /sbin/install-info config(zsh) = 5.0.2-25.el7 coreutils ......(略) [root@localhost Packages]# rpm -q --scripts zsh #查询zsh的自定的脚本片段 postinstall scriptlet (using /bin/sh): if [ ! -f /etc/shells ] ; then echo "/bin/zsh" > /etc/shells else grep -q "^/bin/zsh$" /etc/shells || echo "/bin/zsh" >> /etc/shells fi if [ -f /usr/share/info/zsh.info.gz ]; then # This is needed so that --excludedocs works. /sbin/install-info /usr/share/info/zsh.info.gz /usr/share/info/dir --entry="* zsh: (zsh). An enhanced bourne shell." fi : preuninstall scriptlet (using /bin/sh): if [ "$1" = 0 ] ; then if [ -f /usr/share/info/zsh.info.gz ]; then # This is needed so that --excludedocs works. /sbin/install-info --delete /usr/share/info/zsh.info.gz /usr/share/info/dir --entry="* zsh: (zsh). An enhanced bourne shell." fi fi : postuninstall scriptlet (using /bin/sh): if [ "$1" = 0 ] ; then if [ -f /etc/shells ] ; then TmpFile=`/bin/mktemp /tmp/.zshrpmXXXXXX` grep -v '^/bin/zsh$' /etc/shells > $TmpFile cp -f $TmpFile /etc/shells rm -f $TmpFile fi fi [root@localhost Packages]# rpm -q --whatprovides 'config(zsh)' #查询conig(zsh)是由哪个包提供的 zsh-5.0.2-25.el7.x86_64 [root@localhost Packages]# [root@localhost Packages]# rpm -q --whatrequires 'config(zsh)' #查询config(zsh)被哪个包所依赖 zsh-5.0.2-25.el7.x86_64 [root@localhost Packages]# rpm -qpl zenity-3.8.0-5.el7.x86_64.rpm #这里的zenity是没有安装的,可以直接加-p选项,进行查询操作,查询zenity安装后生成的文件列表 /usr/bin/zenity /usr/share/doc/zenity-3.8.0 /usr/share/doc/zenity-3.8.0/AUTHORS /usr/share/doc/zenity-3.8.0/COPYING /usr/share/doc/zenity-3.8.0/NEWS ......(略) [root@localhost Packages]# rpm -qp --provides zenity-3.8.0-5.el7.x86_64.rpm #查询zenity所提供的CAPABILITY zenity = 3.8.0-5.el7 zenity(x86-64) = 3.8.0-5.el7
五、 校验
rpm {-V|--verify} [select-options] [verify-options] 选项: --nodeps:不检查文件的依赖性关系 --nofiles:不检查文件的任何属性 --nosize:不检查文件大小 --nouser:不检查文件的属主 --nogroup:不检查文件的属组 --nomtime:不检查文件的时间戳
举例:
[root@localhost Packages]# rpm -V zsh .......T. c /etc/zshrc #这里表示时间戳有变,没有任何输出代表校验成功 这里的每个点代表一个校验的类型: 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
我们在这个文件里面添加一行试试:
再来校验:
[root@localhost Packages]# rpm -V zsh S.5....T. c /etc/zshrc #文件大小发生改变,MD5值改变,时间戳改变 [root@localhost Packages]# rpm -V --nomtime zsh #不检查时间戳 S.5...... c /etc/zshrc
包来源合法性验证和完整性验证:
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
[root@localhost Packages]# rpm -K zsh-5.0.2-25.el7.x86_64.rpm zsh-5.0.2-25.el7.x86_64.rpm: rsa sha1 (md5) pgp md5 OK
六、RPM的数据库
rpm {--initdb|--rebuilddb} [--dbpath DIRECTORY] [--root DIRECTORY] --initdb:初始化数据库,当前无任何数据库可实始化创建一个新的;当前有时不执行任何操作; --rebuilddb:重新构建,通过读取当前系统上所有已经安装过的程序包进行重新创建;
一般情况下我们都不要去动RPM的数据库。
总结:rpm命令的查询功能是非常的重要的,但是安装却不显的那么重要,因为使用rpm安装包,如果包存在一些依赖的包,你需要将依赖的包一个一个的安装,这样耗时又耗力,所以在安装包的时候,我们一般会使用比较自动化的工具yum,它能帮我们解决依赖性的关系,yum将在下一篇博客中进行详细的介绍。