• rpm 程序包管理介绍


    API:application program interface

    ABI:application binary interface

    linux系统的ABI文件是ELF格式的

    windows系统的ABI文件是exe,msi格式的

    系统级开发语言:c/c++

    ​ 作品:httpd,vsftpd,nginx

    应用级开发:java/python/php

    ​ java作品:hadoop,hbase

    ​ python作品:openstack

    在linux安装软件非常费劲,分源代码编译安装,二进制安装

    • 编译安装:需要有编译环境,比如需要有gcc等。

      源代码-->目标系统下的二进制格式(可执行程序,库文件,配置文件,帮助文件)-->组织成一个或多个“包”文件

    • 二进制安装(已经把源代码编译成了可以直接执行的程序了)

    程序包管理器

    • Debian:dpt,dpkg。文件名后缀是".deb"
    • redhat:rpm。文件名后缀是".rpm"
    • S.U.S.E:rpm。文件名后缀是".rpm"
    • Gentoo:ports
    • ArchLinux

    源代码文件名解读:name-version.tar.gz

    • version:major.minor.release

      major:主版本号,当有大的变动时,才更新主版本号

      minor:添加一些小的功能,更新小版本号

      release:修正bug,更新此号

    rpm文件名解读:name-version-release.arch.rpm

    • version:major.minor.release(和源代码一样)

    • release:rpm包的发行号。

      虽然源代码相同,但是打包的方法不同,就更新此号

      release.OS:适用的操作系统。2.el7.i386.rmp

    • arch:cpu架构。i386代表是32位系统;x64(amd64)代表是64位系统

      ppc(power pc);noarch(所有架构的适用)

    • 例子:redis-3.0.2-1.centos7.x64.rpm

      redis是name;3.0.2是version;1是rpm包的发行号;centos7是适用的操作系统;x64是cpu架构

    包组成

    很多程序,都是由主程序和许多部件构成,有的用户只想使用主程序,有的用户使用主程序和别的部件。

    所以为了能够达到按需安装,就把包拆成许多子包。主程序的安装包是主包;其他部件的安装包是子包。

    • 主包的名字:name-version-release.arch.rpm

    • 子包的名字:name-function-version-release.arch.rpm

      function:devel,utils,libs等。其实就是部件的名字。

    依赖关系

    linux的哲学是,程序尽量小,组成多个小程序完成复杂功能,所以就导致了,当要安装A,A又依赖B,等。

    为了能够自动安装依赖,就产生了前端工具。

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

    • yum:rhel,centos系类上的rpm包管理器的前端工具
    • apt-get(apt-cache):deb包管理器的前端工具
    • zypper:suse的rpm包管理器的前端工具
    • dnf:centos8,fedora 22+上的rpm包管理器的前端工具

    程序包管理器

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

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

    • 文件清单
    • 安装或卸载时运行的脚本

    2,公共数据库:存放在/var/lib/rpm目录

    • 程序包的名称和版本
    • 依赖关系
    • 功能说明
    • 安装生成的各文件的文件路径和校验码信息
    • 等等
    # ls /var/lib/rpm
    Basenames     __db.001  __db.003  Group       Name          Packages     Requirename  Sigmd5
    Conflictname  __db.002  Dirnames  Installtid  Obsoletename  Providename  Sha1header   Triggername
    

    Group:把包分组后,就可以对组管理,以组位单位的安装,卸载等管理操作。

    Sigmd5:校验码

    Triggername:触发器名称

    Conflictname:包有得版本冲突

    获取程序包的途径

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

    2,开发这个程序的官方站点

    比如nginx的官方站点

    3,第三方组织

    一定要校验获得的程序包,防止获得的是被别人修改过的。

    一般官方提供的包都有对应的md5校验吗,用md5校验器,校验下载的包,生成的MD5校验码如果和官方提供的一样,则说明此包没有被修改过,可以放心使用。

    centos上rpm命令管理程序包

    通用选项:

    • -v:显示详细信息
    • -vv:更详细的详细

    管理包括:安装,升级,卸载,查询和校验,还有数据库维护

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

    • 例子:rpm -ivh Packagename

      # rpm -ivh  zsh-5.0.2-33.el7.x86_64.rpm
      Preparing...                          ################################# [100%]
      Updating / installing...
         1:zsh-5.0.2-33.el7                 ################################# [100%]
      
    • 显示安装进度:-h

      输入#,每个#代表2%的进度

    • 测试安装:--test

      检查有没有冲突:

      显示:error: Failed dependencies,说明依赖没有安装,导致此包不能安装。

      # rpm -ivh --test php-common-7.3.5-3.module_el8.1.0+252+0d4e049c.x86_64.rpm
      warning: php-common-7.3.5-3.module_el8.1.0+252+0d4e049c.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 8483c65d: NOKEY
      error: Failed dependencies:
              libcrypto.so.1.1()(64bit) is needed by php-common-7.3.5-3.module_el8.1.0+252+0d4e049c.x86_64
              libcrypto.so.1.1(OPENSSL_1_1_0)(64bit) is needed by php-common-7.3.5-3.module_el8.1.0+252+0d4e049c.x86_64
              libssl.so.1.1()(64bit) is needed by php-common-7.3.5-3.module_el8.1.0+252+0d4e049c.x86_64
              libssl.so.1.1(OPENSSL_1_1_0)(64bit) is needed by php-common-7.3.5-3.module_el8.1.0+252+0d4e049c.x86_64
      
      
    • 忽略依赖,强行安装:--nodeps

      不建议使用,处分依赖的是帮助文档。

    • 重新安装:--replacepkgs

      用途:当程序使用的配置文件被改坏了,自己不能修复到安装后的状态了,先删除此文件,然后使用--replacepkgs重新安装,就会把配置文件修复成安装后的状态。注意,如果不删除此文件的话,即使使用--replacepkgs也没有作业,会保留原来的配置文件。

      # rpm -ivh --replacepkgs zsh-5.0.2-33.el7.x86_64.rpm
      Preparing...                          ################################# [100%]
      Updating / installing...
         1:zsh-5.0.2-33.el7                 ################################# [100%]
      
      
    • 安装和卸载时的脚本:有4中脚本

      • 安装开始前运行的脚本:preinstall。不行运行此脚本:--nopre
      • 安装完成后运行的脚本:postinstall。不行运行此脚本:--nopost
      • 卸载开始前运行的脚本:preuninstall。不行运行此脚本:--nopreun
      • 卸载完成后运行的脚本:postuninstall。不行运行此脚本:--nopostun
      • 四个脚本都不运行:--noscripts
    • 安装时不检查包完整性:--nodigest

      Don't verify package or header digests when reading.

      # rpm -ivh --nodigest zsh-5.0.2-33.el7.x86_64.rpm
      Preparing...                          ################################# [100%]
      Updating / installing...
         1:zsh-5.0.2-33.el7                 ################################# [100%]
      
    • 安装时不检查不检查包的签名信息,不检查来源合法性:--nosignature

      Don't verify package or header signatures when reading.

      # rpm -ivh --nosignature zsh-5.0.2-33.el7.x86_64.rpm
      Preparing...                          ################################# [100%]
      Updating / installing...
         1:zsh-5.0.2-33.el7                 ################################# [100%]
      

    升级:使用的选项和安装一样

    • 安装或升级:rpm {-U|--upgrade} [install-options] PACKAGE_FILE ...

      # rpm -Uvh --nodigest zsh-5.0.2-33.el7.x86_64.rpm
      Preparing...                          ################################# [100%]
              package zsh-5.0.2-33.el7.x86_64 is already installed
      
    • 只能升级:rpm {-F|--freshen} [install-options] PACKAGE_FILE ...

      # rpm -Fvh --nodigest zsh-5.0.2-33.el7.x86_64.rpm
      
    • 升级时专用的选项

      • --oldpackage:降级。新版本有问题,所以需要降级回原来的版本
      • --force:忽略依赖,强制升级
    • 注意:

      • 不要对内核做升级操作,linux支持多内核并存,因此直接安装新内核。
      • 如果配置文件做过修改,升级时,新版本不会覆盖原来的文件,而是把新文件重命名成filename.rpmnew后提供。

    卸载:rpm {-e|--erase} [--allmatches][--justdb] [--nodeps][--noscripts] [--test] PACKAGE_NAME ...

    卸载的时候,指定的是package_name,安装/升级时指定的是file_name

    # rpm -e zsh
    # rpm -ql zsh
    package zsh is not installed
    
    • 卸载所有版本的package_name:--allmatches
    • 忽略依赖关系:--nodeps

    查询:rpm {-q|--query} [select-options][query-options]

    select-options:

    • 查看安装的所有包:-a,--all

      # rpm -qa
      
    • 查看某个文件是属于哪个包的:-f file

      # rpm -qf /usr/share/doc/zsh-5.0.2
      zsh-5.0.2-33.el7.x86_64
      

    query-options:

    • 查看rpm包的changelog(不是源码的):--changelog

      # rpm -q --changelog zsh
      
    • 查看rpm包安装完成后,都生成了哪些文件:-l

      # rpm -ql zsh
      
    • 查看这个包的版本号,大小,包组等:-i

      # rpm -qi zsh
      
    • 查询包所使用的配置文件:-c

      # rpm -qc bash
      /etc/skel/.bash_logout
      /etc/skel/.bash_profile
      /etc/skel/.bashrc
      
    • 查询包所提供的帮助文件:-d

      # rpm -qd bash 
      /usr/share/doc/bash-4.2.46/COPYING
      /usr/share/info/bash.info.gz
      /usr/share/man/man1/..1.gz
      /usr/share/man/man1/:.1.gz
      /usr/share/man/man1/[.1.gz
      ...
      
    • 查询包所提供的capabilities:--provides

      # rpm -qd bash | less
      [root@localhost ~]# rpm -q --provides zsh
      config(zsh) = 5.0.2-33.el7
      zsh = 5.0.2-33.el7
      zsh(x86-64) = 5.0.2-33.el7
      # rpm -q --provides bash
      /bin/bash
      /bin/sh
      bash = 4.2.46-31.el7
      bash(x86-64) = 4.2.46-31.el7
      config(bash) = 4.2.46-31.el7
      

      根据capability的名字,查询这个capability是由哪个包提供的:--whatprovides

      # rpm -q --provides bash
      /bin/bash
      /bin/sh
      bash = 4.2.46-31.el7
      bash(x86-64) = 4.2.46-31.el7
      config(bash) = 4.2.46-31.el7
      # rpm -q --whatprovides bash
      bash-4.2.46-31.el7.x86_64
      # rpm -q --whatprovides 'config(bash)'#注意:需要用引号括起来,由于有括号。
      bash-4.2.46-31.el7.x86_64
      
      

      根据capability的名字,查询这个capability是由哪些包所依赖:--whatrequires

      没有任何包依赖zsh,但有很多包依赖bash。

      发信有n多包依赖:libc.so.6()(64bit)

      # rpm -q --whatrequires zsh
      no package requires zsh
      # rpm -q --whatrequires bash
      bash-completion-2.1-6.el7.noarch
      dracut-033-554.el7.x86_64
      initscripts-9.49.46-1.el7.x86_64
      lvm2-2.02.180-8.el7.x86_64
      autofs-5.0.7-99.el7.x86_64
      jline-1.0-8.el7.noarch
      rsyslog-8.24.0-34.el7.x86_64
      PackageKit-command-not-found-1.1.10-1.el7.centos.x86_64
      kpatch-0.6.1-1.el7.noarch
      # rpm -q --whatrequires 'libc.so.6()(64bit)'
      
    • 查看某个包依赖哪些capability:-R

      查看

      # rpm -qR bash
      /bin/sh
      config(bash) = 4.2.46-31.el7
      libc.so.6()(64bit)
      libc.so.6(GLIBC_2.11)(64bit)
      libc.so.6(GLIBC_2.14)(64bit)
      libc.so.6(GLIBC_2.15)(64bit)
      libc.so.6(GLIBC_2.2.5)(64bit)
      libc.so.6(GLIBC_2.3)(64bit)
      libc.so.6(GLIBC_2.3.4)(64bit)
      libc.so.6(GLIBC_2.4)(64bit)
      libc.so.6(GLIBC_2.8)(64bit)
      libdl.so.2()(64bit)
      libdl.so.2(GLIBC_2.2.5)(64bit)
      libtinfo.so.5()(64bit)
      rpmlib(BuiltinLuaScripts) <= 4.2.2-1
      rpmlib(CompressedFileNames) <= 3.0.4-1
      rpmlib(FileDigests) <= 4.6.0-1
      rpmlib(PayloadFilesHavePrefix) <= 4.0-1
      rtld(GNU_HASH)
      rpmlib(PayloadIsXz) <= 5.2-1
      
    • 查询包里的脚本:--scripts

      发现zsh包里包含:postinstall,preuninstall,postuninstall

      # rpm -q --scripts 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
      
    • 查询为安装的包的信息,上面的选项都适用,但不能使用package_name,要使用package_file

      # rpm -ql zsh
      package zsh is not installed
      # rpm -qpl zsh-5.0.2-33.el7.x86_64.rpm
      /bin/zsh
      /etc/skel/.zshrc
      /etc/zlogin
      /etc/zlogout
      ...
      
      # rpm -qpR zsh-5.0.2-33.el7.x86_64.rpm
      # rpm -qp --scripts zsh-5.0.2-33.el7.x86_64.rpm
      

    校验:rpm {-V|--verify} [select-options][verify-options]

    # rpm -V zsh#没有回显说明没有人篡改过
    # rpm -ql zsh | less
    # file /etc/zlogin
    /etc/zlogin: ASCII text
    # emacs -nw /etc/zlogin#故意修改一下
    # rpm -V zsh#再次校验,回显下面的信息
    S.5....T.  c /etc/zlogin
    

    校验结果解读:

    • S 文件大小变了
    • M Mode变了
    • 5 文件内容变了,导致MD5校验后,和之前的不一样
    • D 设备的主/次设备号不匹配
    • L readLink(2) path mismatch
    • U 属主变了
    • G 属组变了
    • T mTime(修改时间)变了
    • P caPabilities(功能)变了

    校验包的完整性和来源合法性

    公钥在哪里,一般在机构CA里,但是系统光盘上有公钥,当安装完系统后,会把光盘上的公钥存放在/etc/pki/rpm-gpg/目录。

    # ls /etc/pki/rpm-gpg/
    RPM-GPG-KEY-CentOS-7  RPM-GPG-KEY-CentOS-Debug-7  RPM-GPG-KEY-CentOS-Testing-7
    

    导入公钥:# rpm --import file

    # rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
    

    公钥导入后,在安装的同时会自动校验包的完整性和来源合法性

    手动校验rmp包:前提是已经导入了公钥

    # rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
    # rpm -K zsh-5.0.2-33.el7.x86_64.rpm
    zsh-5.0.2-33.el7.x86_64.rpm: rsa sha1 (md5) pgp md5 OK
    

    第三方组织(比如epel)的公钥去哪里找,去epel的官网下载。

    rpm数据库

    想一想,rpm查询和校验时,是从哪里读取的信息呢?

    当安装rpm包时,会把包的详细信息插入到本地数据库,所以才能实现以后的查询和校验操作。

    本地rpm包的数据库路径:/var/lib/rpm

    # ls /var/lib/rpm
    Basenames     __db.001  __db.003  Group       Name          Packages     Requirename  Sigmd5
    Conflictname  __db.002  Dirnames  Installtid  Obsoletename  Providename  Sha1header   Triggername
    

    所以rpm数据库太重要了,如果损坏了,就需要重建。

    数据库重建:rpm {--initdb|--rebuilddb} [-v][--dbpath DIRECTORY] [--root DIRECTORY]

    centos6获取帮助:man rpm

    centos7获取帮助:man rpmdb

    从0创建数据库:--initdb

    根据系统里留存的rpm的header文件从新构建数据库:--rebuilddb

    在指定路径创建/更新数据库:--dbpath DIRECTORY

    # rpm --initdb --dbpath=/tmp/rpmdb
    # ls /tmp/rpmdb/
    Basenames     __db.001  __db.003  Group       Name          Packages     Requirename  Sigmd5
    Conflictname  __db.002  Dirnames  Installtid  Obsoletename  Providename  Sha1header   Triggername
    # rpm --rebuilddb --dbpath=/tmp/rpmdb
    # ls /tmp/rpmdb/
    Basenames     Dirnames  Installtid  Obsoletename  Providename  Sha1header  Triggername
    Conflictname  Group     Name        Packages      Requirename  Sigmd5
    
    
    # c/c++ 学习互助QQ群:877684253 ![](https://img2018.cnblogs.com/blog/1414315/201811/1414315-20181106214320230-961379709.jpg) # 本人微信:xiaoshitou5854
  • 相关阅读:
    使用layer.tips实现鼠标悬浮时触发事件提示消息实现
    鼠标移入、移出触发事件实现
    vue组件独享守卫钩子函数参数详解(beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave)
    vscode 向下复制当前行(即visual studio 中的Ctrl + D)功能快捷键
    vue UI可视化窗口修改为显示中文
    js中的匿名函数
    NPM install -save 和 -save-dev 傻傻分不清
    Node.js中package.json中库的版本号详解(^和~区别)
    RTX管理器里怎么建群
    Mysql的timestamp(时间戳)详解以及2038问题的解决方案
  • 原文地址:https://www.cnblogs.com/xiaoshiwang/p/12312725.html
Copyright © 2020-2023  润新知