Linux程序包管理

 

         我们linux操作系统从底层到高层的层次结构:

最底层首先是硬件,计算机的计算能力都是在硬件逻辑上设计实现的,而不同厂商生产的芯片哪怕是同一厂商生产的同一型号的芯片,他们给我们提供的计算接口都不一样,我们基本都同说过嵌入式开发,那么这种开发如果没有系统可以使用的话,主要是面向硬件,来写程序的,而这种程序只能适应一种或者几种有限的芯片,单片机尤其如此,现在很多嵌入式开发过程中,也已经有了一种通用层来实现,但是像单片机这种还是面向硬件编程的,

         然后在底层之上就是将硬件接口封装起来的操作系统层,系统层将底层的硬件接口封装起来以后,通过系统调用(system  call),向上输出,但是系统调用仍然很底层,为了加速开发操作,在操作系统层之上又加了半层叫“库(lib  call”,注意这里不是全层,而是半层,因为对于程序员来讲,可以面向半层“库”来写程序,也可以面向我们的操作系统来写程序,然后在库之上就是应用程序了,应用程序是给我们真正带来一些生产力的,我们的内核是不能完成任何具体的操作的,在这众多的应用类型程序中,我们知道有一类比较独特的,他主要是让用户跟主机交互的,shell任何利用操作系统完成任务的操作,都是通过应用程序完成的,所以我们说将来我们真正去实现运维操作的过程中,除了系统管理,库调用管理之外,其实作为运维人员来讲,就是不停的在我们的操作系统上安装配置某一应用程序包,然后让这个应用程序包运行起来,并提供服务,或者利用此工具完成某种具体相应操作的过程。那对于我们运维人员来讲,安装卸载管理程序包,是实现很多后期工作的最基础,最根本的任务,所以首先我们要学会灵活实现对于程序包的安装管理操作。

         任何程序的运行,他有可能在程序包上提供两种格式的程序包,我们称之为源码包或者叫二进制包,那么我们将到这就不得不回顾一下以前讲到的APIABIAPI叫应用程序开发接口,ABI叫应用程序二进制接口。我们说过,API层次兼容未必ABI层次兼容。因为有些操作系统他们执行程序的格式,或者对二进制的是识别格式,并非是相同的,像linux跟类unixUnix-like)他们的操作系统,一般而言是相同的,他们的ABI是相同的,但是与windows相差很远,比方说windows系统上的可执行程序都是exe或者是msi的,而linux上的是elf格式的。所以他们在ABI层次不兼容,所以我们说即使我们使用高级编程语言,去编写程序,他们即便是在源码格式兼容的,但是一旦编译成功以后,本来是linux上面的格式的,而跑到windows上一样依然无法运行。所以有一个程序包,在linux上编译好了,他是二进制格式的,我们是不能拿来装到windows之上的。反过来如果一个程序包在windows上编译好了,是一个exe格式的文件,能不能在linux系统上运行起来呢?也很难。我们可以借助虚拟化将二者的差异将其磨平了,比方说现在的各种各样的应用程序,几乎都是针对库调用来开发的,很少说是直接通过系统调用来实现。即使是通过系统调用来实现,那也没问题,现在在windows上有很多程序模拟linux的库,在linux上也有很多模拟windows库的程序。

         比方说现在这里有一个linux操作系统,没关系我们装一个WinE,这个wine就能在linux上模拟出windows库来。所以我们就可以借助wine来运行windows应用程序。比方说希望在linux上玩的各种各样的游戏,甚至还能给我们提供一个安装的路径,模拟出windows上的CDE盘。但这只是一个库虚拟层。同样在windows上我们也能提供linux运行环境。叫cywin,在windows之上运行一个cywin,他能够提供运行模拟出linux的运行环境来。所以说有一些程序只能在linux上运行的话,我们也能在windows上基于cywin运行起来,比如说像docker。这都不是正常的方案,正常的方案就是,由于abf库是不兼容的,至少在二进制层次上他们是不兼容的。所以他们没有办法安装块系统来实现系统调用。

         库级别的虚拟化:我们可以借助库级别的虚拟化来抹平他们的不同。比如在linux上我们可以借助于wine来提供windows库从而能够运行windows应用程序。而在Windoes上我们借助于Cywin这个程序包,来虚拟模拟出linux的运行环境。从而使得那些二进制程序也能跨系统来运行了。

 

系统级开发:

         C/C++:服务及应用程序:httpdvsftpdnginx

         go

应用级开发

         java/Python/perl/ruby/php

                   javahadoophbase,(他们的运行需要jvm就是java虚拟机)

                   Pythonopenstackopenstack是一个云操作系统)

                            运行Python程序需要用到pvmPython虚拟机)

                            运行perl:(依赖于perl

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

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

 

C/C++程序格式:

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

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

 

(二进制格式我们仅仅是指他的陈序和库是二进制的,他的配置文件和帮助文件当然是文本的。我们知道Linux重要的哲学思想之一就是:用文本文件保存配置信息,这样带来的好处就在于,我们将来配置任何应用程序时,只需要依赖一款文本编辑器就可以。)

         所以我们将来要想安装应用程序,那么针对我们两种格式的内容,他的安装方式就显然不一样,我们知道源代码不能运行,所以我们必须将其编译以后将其安装运行。对于源代码而言我们要手动把“文本格式的程序代码---->编译器------>二进制格式”这个过程手动完成。如果是别人给我们提供的是二进制格式的文件,上面的过程就不需要我们自己做了。因为我们拿到的直接是可运行格式的。万一很不幸的是对方仅提供了源代码怎么办呢?那么我们就只能自己编译了。而要想能够自己编译的话,那就依赖于编译开发环境。因为编译要依赖于编译器,依赖于头文件,依赖于开发库。我们的库也是源代码格式的,所以库也有两种文件。后来我们把它编译成了二进制格式的。

         所以我们的编译开发环境依赖于:编译器,头文件,开发库。

如果我们拿到的是二进制格式的,那么就不需要编译,我们直接放到目录下就能运行起来了。

所以我们如果要执行源代码编译安装,那么我们需要额外的准备好几步。至少我们要想方设法保证我们的编译环境是完整的。而提供编译环境是相当劳心费神的工作。

         我们学习程序包安装,首先了解二进制格式是怎么安装的,然后再去了解如何源代码编译安装。上面是C程序的格式。

         那么如果是应用级的程序格式呢?

那么我们就以JAVAPython为例,那么JAVAPython应用程序格式是一样的,

         java/python程序格式:

                   源代码

                   二进制

同样的道理,如果是源代码格式,那也只能编译了,如果是二进制格式那么直接使用即可

但是他们的编译不同在于,他们编译出来的不是二进制格式,或者不是能够直接在CPU上直接运行的二进制格式,而是编译成其能够在虚拟机上(jvm/pvm)运行的程序格式。也就是说通过虚拟机将其转换成能够运行的二进制格式。中间多了一层,所以性能很差。或者说比起C语言性能比较差。通常来说无论是C格式的源代码,还是java格式的源代码,通常他们的程序文件,都不止一个。那为什么不止一个?

         将来我们的程序文件在编译时存在错综复杂的依赖关系,导致我们有一百个程序源文件,很有可能我们先编译第一个,在编译第三个,在编译第二个。因为第一个第三个被第二个所依赖。这样带来的结果就是谁先编译谁后编译,作为使用者我们没有能力管理他们的编译顺序。所以各种各样的源代码通常都使用一个项目管理工具。或者叫项目构建工具。

 

         项目构建工具:

                   C/C++:最著名的项目构建工具就叫make

                   java:最经典的项目构建工具就叫maven

这样项目构建工具,也必须依赖项目开发环境才能构建。而对于java来讲他也有自己的开发环境。他也需要开发环境。只不过对于这两种的编程语言来讲。他们的开发环境,通常指的是,那个对应应用程序的虚拟机,和虚拟机上面的编译器。java源代码编译也需要开发环境,只不过是没有头文件,他们也需要:编译器,卡发库。这也是我们程序包的组成格式。

         为了降低初级使用者的难度,我们应该怎样做?

我们应该使用程序包管理器,来协助这些终端用户的管理工作。

 

         程序包管理器:

                   源代码---->目标二进制格式----->组织成为一个或有限几个“包”文件;

                            安装,升级,卸载,查询,(甚至对linux上还支持)校验

 

         程序包管理器:

                   (程序包管理器大体上有哪几种呢?

对于windows来讲,大多数的应用程序都是exe格式的。这种格式应用程序给我们提供一个安装界面,我们只需点击下一步下一步即可,卸载的时候我们通过我们控制面板中的,卸载应用程序来实现,为什么我们能看到的只是下一步下一步就能完成安装呢?他其实就是通过一个程序包管理器打包成一个单个的exe文件,我们知道我们安装完以后他的确分散成多个可能放在program/files目录下某一个路径下,每一个应用程序都有一个目录,里面存放各种文件,有二进制的有库的,对于windows来说,他们的库是dll文件,动态链接库,dynamic link,而对于linux而言,叫so。)

         目前linux有三大主流分支:

                   debiandpt,dpkg,".dep"

                   redhatredhat   package manager,简称:rpm".rpm"rpm ispackage manager

                   S.u.S.Erpm".rpm"

 

                   Gentooports

                   ArchLinux

 

源代码:

         命名方式:name-VERSION.tar.gz

                   VERSIONmajor.minor.release               //主版本号.次版本号.发行版本

rpm包命名格式:

         name-VERSION-release.arch.rpm            //releaserpm包的release

                   VERSIONmajor.minor.release

                   release.arc:是指rpm包的发行号

                            release.os2.el7.i386.rpm

                            archetecture:架构,i386x64amd64),ppcnoarch

 

                   redis-3.0.2.targz----->redis-3.0.2-1.centos7.x64.rpm

                  

changelog

 

拆包:主包和支包

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

         支包:name-function-VERSION-release.arch.rpm

                            functiondevel,utils,libs.....

 

依赖关系:

         x,y,z

                   x------依赖--->y,z

                            y------依赖-------->A,B,C

                            c--------->y

 

        

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

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

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

                   zyppersuserpm管理器前端工具;

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

 

程序包管理器:

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

 

         1.程序包的组成清单(每个程序包都单独实现);

                   文件清单

                   安装或卸载时运行的脚本

         2数据库(公共)

                   程序包的名称和版本;

                   依赖关系;

                   功能说明;

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

 

                  

 

CentOS系列系统的rpm数据库:路径

         /var/lib/rpm

[root@centos7 ~]# ls /var/lib/rpm

Basenames     __db.002 Group       Obsoletename  Requirename Triggername

Conflictname  __db.003 Installtid  Packages      Sha1header

__db.001      Dirnames Name        Providename   Sigmd5

[root@centos7 ~]#

 

         解释:

Group:包组,我们可以将程序划分成一个组,将来可以把一个程序包组全部安上,一个组                     全部卸载。

Name:各个程序的名字;

Sigmd5MD5的校验码;

Triggername:触发器名称;

 

获取程序包的途径:

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

                            http://mirrors.aliyun.com

                            http://mirrors.sohu.com

                            http://mirrors.163.com

 

         2)项目的官方站点

                            举例:以thhp为例:站点httpd.apache.org

         或者:

                            网站www.zabbix.com

打开网站www.zabbix.com网站,我们网站的导航栏中直接点击“Download”,打开一个页面,前面的“Zabbix  Packages”是zabbixrpm,再往下“Zabbix  Sources”是源码包

         所以说很多项目的官方站点也提供rpm包,并且我们一定注意,既然后能用rpm包安装的我们一定不要使用源码包编译安装。

 

         3)第三方组织:EPEL

                            EPEL红帽官方的社区组织所维护的,发行光盘之外其他他们觉得比较有用比较重点,比较有名的程序包,都将制作成rpm包放在EPEL中。

         其实国内的很多官方站点都有这样的epel

         举例演示,我们以“mirrors.aliyun.com”为例:

在镜像阿里云的站点上“mirrors.aliyun.com”也有epel,在epel中会为我们的centos提供了众多的额外的补充包。

                   aEPEL

                   b)搜索引擎

                                     http://pkgs.org(在rpm领域中,这是一个非常重要的);

                                     rpmfind.net(要想搜哪个文件包直接搜。)

                                     rpm.pbone.net

wKiom1gyvnKzGLlNAAA-xpAGZgo055.png

上面对话框中,我们可以输入正确的内容来进行查询,我们还可以通过后面的


Advanced RPM Search

来进行高级查询。

         4)自己手动制作rpm包。

 

注意:不管上面的那种方式获得rpm包,只要是通过互联网上获得的,那么我们就可以认为即使原作者在里面没有做任何改变,或者修改,因为我们现在经常使用一些下载工具,像迅雷,那这种工具有点问题,为什么这种工具他的下载的速度非常的块,就是因为他们可能不是从官方的原站点下载的,或者是非完完全全的官方站点上下载的,其实从已经下载的用户的那里下载的,如果官方站点下载不到的话,而且这时候他恰恰搜索到某个用户的那里有这个文件,他也会传给你,但是这个文件可能被其他用户精心的修改过,制作了后门,所以以后我们在互联网上下载人格安全性较高的文件的,像银行官方站点的插件,还有像支付宝的证书等,我们就不应该在使用迅雷下载。以后这中工具少用,尤其是使用PHP下载的,是相当危险的,那么我们下载下来一个工具我们不知道他到底是不是官方提供的呢?

至少是所有的数据没有被篡改过,那怎么办呢?

         我们建议要做MD5校验,提供一个MD5校验器,检验其合法性,来源合法性。

         程序包的完整性要做校验;

 

 

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

                   安装,升级,卸载,查询和校验,数据库的维护

上面提到的“安装,升级,卸载,查询和校验”都用rpm命令来实现。

                   格式: rpm [OPTIONS]  [PACKAGE_FILE]

 

         安装用到的选项:-i=--install

         升级用到的选项:-U=--update,  -F=--freshen

         卸载:-e=--erase

         查询:-q=--query

         校验:-V=--verify

         数据库维护:--builddb,--initdb

 

 

 

 

         安装:

                   安装时必须有对应的文件才行。

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

                           

                            真正安装的时候应该使用选项:-ivh

                                              rpm -ivh  PACKAGE_FILE......

 

                                        GENERAL OPTIONS(通用选项)

                                                        -vverbose;(输出相信信息)

                                                        -vv:(输出更详细的过程信息)

        

                                               [install-options]

                                                        -hhash  marks输出进度条;每个#表示2%的进度;

                                                        --test:如果不想真正的安装,仅仅是检查一下有没有潜在的冲                                                                               突的可能我们就可以测试安装,检查并报告依赖关系及                                                                           冲突消息等;

                                                        --nodeps:忽略依赖关系;不建议;

                                                        --replacepkgs:重新安装  (如果某个包安装过,但是后来我们                                                                                       更改了他的配置文件,出了错,那我们刻意先卸载                                                                                    再重新安装,但是我们还有一个更好的方法就是,                                                                               直接重新安装。)

                                                        --noscripts

                                                        --oldpackage:降级用的

                                                        --justdb:只是升级一下数据库。

 

         注意rpm包可以自带脚本:

                            这些脚本有四类:

                                     如果这四类都不想执行:--noscripts

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

                                     postinstall:安装过程完成以后运行的脚本,%post           --nopost

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

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

 

                                                        --nosignature:不检查签名信息,不检查来源合法性;

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

 

 

 

 

 

举例演示:

[root@centos6 Packages]# rpm -ivh zsh-4.3.11-4.el6.centos.2.x86_64.rpm

warning:zsh-4.3.11-4.el6.centos.2.x86_64.rpm: Header V3 RSA/SHA1 Signature, key IDc105b9de: NOKEY

Preparing...                ###########################################[100%]

  1:zsh                   ########################################### [100%]

[root@centos6 Packages]# cat /etc/shells

/bin/sh

/bin/bash

/sbin/nologin

/bin/dash

/bin/tcsh

/bin/csh

/bin/zsh

[root@centos6 Packages]#

 

 

演示重新安装replacepkgs

 

之前我们zsh已经安装过了,那我们先编辑一下zsh的配置文件“/etc/zshrc”,比方说我们删除其中的几行,然后保存,因为我们执行“wq”之后,他的配置文件信息就不能恢复了。那么这时,我们

[root@centos6 media]# vim /etc/zshrc                   //先将zsh的配置文件中的内容删除一部分

[root@centos6 media]# cat /etc/zshrc

 [root@centos6media]#rpm -ivh --replacepkgs /media/Packages/zsh-4.3.11-4.el6.centos.2.x86_64.rpm

 [root@centos6media]# cat /etc/zshrc                 //发现配置文件内容没有恢复,这时因为我们的系统在我们没有将原先的配置文件删除,就在重装软件,那么系统就会认为我们这个配置文件修改是有目的的,我们也要记住replacepkgs是不能修改原来的配置文件的。所以我们在重装之前要先删除配置文件。

 

 [root@centos6media]# rm -f /etc/zshrc

[root@centos6 media]# rpm -ivh --replacepkgs/media/Packages/zsh-4.3.11-4.el6.centos.2.x86_64.rpm

 [root@centos6media]# cat /etc/zshrc                   //发现配置文件内容恢复了

#

# /etc/zshrc is sourced in interactiveshells.  It

# should contain commands to set upaliases, functions,

# options, key bindings, etc.

#

 

## shell functions

#setenv() { export $1=$2 }  # csh compatibility

 

# Set prompts

PROMPT='[%n@%m]%~%# '    # default prompt

#RPROMPT=' %~'     # prompt for right side of screen

 

# bindkey -v             # vi key bindings

# bindkey -e             # emacs key bindings

bindkey ' ' magic-space  # also do history expansion on space

 

_src_etc_profile_d()

{

   #  Make the *.sh things happier,and have possible ~/.zshenv options like

    #NOMATCH ignored.

   emulate -L ksh

 

 

    #from bashrc, with zsh fixes

   if [[ ! -o login ]]; then # We're not a login shell

       for i in /etc/profile.d/*.sh; do

             if [ -r "$i" ]; then

                 . $i

             fi

       done

       unset i

   fi

}

_src_etc_profile_d

 

unset -f _src_etc_profile_d

 

[root@centos6 media]#

 

 

 

不检查签名演示:

[root@centos6 media]# rpm -ivh --replacepkgs/media/Packages/zsh-4.3.11-4.el6.centos.2.x86_64.rpm

warning: /media/Packages/zsh-4.3.11-4.el6.centos.2.x86_64.rpm: Header V3RSA/SHA1 Signature, key ID c105b9de: NOKEY

Preparing...               ########################################### [100%]

  1:zsh                   ########################################### [100%

上面在重新安装软件包的时候,前面出现了警告,我们要见检查文件的合法性,文件的完整性,要检查文件的这两个选项,要依赖一个秘钥文件,要依赖这个包制作者的公钥。

[root@centos6 media]# rpm -ivh--replacepkgs --nosignature/media/Packages/zsh-4.3.11-4.el6.centos.2.x86_64.rpm

Preparing...                ###########################################[100%]

  1:zsh                   ########################################### [100%]

[root@centos6 media]#

上面安装时,警告消失。