Linux程序包管理之RPM

一、RPM的簡介

        由於程序源代碼到可被計算機識別並運行的指令是需要多步驟處理的:程序源代碼 --> 預處理 --> 編譯 --> 彙編 --> 鏈接。

        這裏以C,C++爲例做爲說明。程序員寫完C,C++源代碼後需要把源代碼進行預處理,即通過預處理器把源代碼分割或處理成爲特定的符號用來支持宏調用。預處理後進一步通過編譯器(gcc)編譯爲目標代碼(object code),它由接近於機器語言的代碼組成。目標代碼通過編譯器編譯後才能生成可供CPU識別的機器代碼、機器指令。由於C,C++在編寫中大量調用了庫文件,所以在編譯後需要把源代碼中使用到的庫做好鏈接。形成能夠依賴於共享庫獨立運行代碼。

        由源代碼到可被計算機運行的代碼需要預處理、編譯、彙編、鏈接等過程。對於剛接觸LINUX或接觸不深的我們來說是一件不可想象的事。所以有很多志願者或機構把源代碼編譯成可被計算機識別的二進制應用程序打包發佈到網絡上供用戶下載使用。打包的二進制應用程序一般包含(二進制文件、庫文件、配置文件、幫助文件)。由於在LINUX中二進制應用程序的組成部分爲:

二進制程序:/bin, /sbin, /usr/bin, /usr/sbin, /usr/local/bin, /usr/local/sbin

庫文件:/lib, /lib64, /usr/lib, /usr/lib64, /usr/local/lib, /usr/local/lib64

配置文件:/etc, /etc/DIRECTORY, /usr/local/etc

幫助文件:/usr/share/man, /usr/share/doc, /usr/local/share/man, /usr/local/share/doc

此時當用戶拿到編譯好的二進制應用程序後,需要手動分配不同類型的文件,而且當我們要卸載的時候需要去刪除之前的文件。這樣會大大造成不必要的麻煩。就此有了程序包管理的出現。      

        RPM,全稱RPM Package Manager,是由Red Hat推出的軟件包管理系統,現在在各個發行版普遍使用。RPM包管理器,將編譯好的程序打包成一個文件或有限的幾個文件,可用於實現便捷地安裝、卸載、升級、查詢、校驗等程序管理;通常用與RHEL,紅帽衍生系統,如CenOS等系統,用來實現對Linux程序包進行快捷管理。

    ①、程序的組成組成清單 (每個包獨有):文件清單、安裝或卸載時運行的腳本

    ②、數據庫(公共):程序包名稱及版本、依賴關係、功能說明、安裝生成的各文件的文件路徑及校驗碼信息


RPM命名格式爲:

[root@localhost Packages]# ll zsh-html-4.3.10-7.el6.x86_64.rpm 
-r--r--r--. 2 root root 465040 11月 25 2013 zsh-html-4.3.10-7.el6.x86_64.rpm
#rpm包命名方式:name-version(major.minor.release)-rpm.release(rpm.release.OS).arch.rpm

以上rpm包:rpm包名字爲zsh-html,zsh-html程序主版本號爲4,zsh-html程序次版本號爲3,zsh-html程序釋放版本號爲10,rpm包BUG或其他功能修復版本號爲7,el6爲企業LINUX版本6,x86_64爲平臺架構


二、2進製程序所依賴的庫文件

        由於程序包安裝或使用中會大連調用庫文件。所以介紹一下兩個命令。以便以後方便查看程序二進制程序所依賴的庫文件。

查看二進制程序所依賴的庫文件:

[root@localhost Packages]# ldd /bin/ls
	linux-vdso.so.1 =>  (0x00007ffff09ff000)
	libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fd567b05000)
	librt.so.1 => /lib64/librt.so.1 (0x00007fd5678fd000)
	libcap.so.2 => /lib64/libcap.so.2 (0x00007fd5676f8000)
	libacl.so.1 => /lib64/libacl.so.1 (0x00007fd5674f0000)
	libc.so.6 => /lib64/libc.so.6 (0x00007fd56715c000)
	libdl.so.2 => /lib64/libdl.so.2 (0x00007fd566f57000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fd567d2a000)
	libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fd566d3a000)
	libattr.so.1 => /lib64/libattr.so.1 (0x00007fd566b35000)
#       依賴的庫名    => 依賴的庫的路徑(在內存中的位置)

查看本機裝載的庫文件:

[root@localhost Packages]# ldconfig -p
在緩衝區“/etc/ld.so.cache”中找到 248 個庫
	libz.so.1 (libc6,x86-64) => /lib64/libz.so.1
	libxtables.so.4 (libc6,x86-64) => /lib64/libxtables.so.4
	........
	libxml2.so.2 (libc6,x86-64) => /usr/lib64/libxml2.so.2


三、RPM的使用詳細介紹

        前面說了一大堆。好吧。現在開始我們的命令之旅吧!!下面爲RPM管理中常見的使用!!


①、RPM包的安裝

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

        -v: 顯示安裝過程

        -h: 以#顯示程序包管理執行進度;每個#表示2%的進度

[root@localhost Packages]# rpm -ivh zsh-html-4.3.10-7.el6.x86_64.rpm 
Preparing...                ########################################### [100%]
   1:zsh-html               ########################################### [100%]

        

        --test:測試安裝,但不真正執行安裝過程,dry run模式

[root@localhost Packages]# rpm -ivh --test uuid-c++-devel-1.6.1-10.el6.i686.rpm
error: Failed dependencies:
	libossp-uuid++.so.16 is needed by uuid-c++-devel-1.6.1-10.el6.i686
	uuid-c++ = 1.6.1-10.el6 is needed by uuid-c++-devel-1.6.1-10.el6.i686
	uuid-devel = 1.6.1-10.el6 is needed by uuid-c++-devel-1.6.1-10.el6.i686
#這裏,我們使用了--test測試安裝。但是報錯了error: Failed dependencies。這是由於安裝的包依賴於其它包導致的
#可以先安裝其他依賴的包或者使用下面參數忽略忽略依賴關係安裝。但是一般不建議這麼做。


        --nodeps:忽略依賴關係安裝

[root@localhost Packages]# rpm -ivh --nodeps uuid-c++-devel-1.6.1-10.el6.i686.rpm
Preparing...                ########################################### [100%]
   1:uuid-c++-devel         ########################################### [100%]
#上面測試安裝的時候由於包的依賴關係無法安裝。這裏我們忽略依賴關係即可成功安裝,但是一般不推薦這麼做。
#忽略依賴關係安裝一般使用場景。比如兩個包互相依賴,我依賴你,你依賴我,這是要結爲夫妻的節奏。此時可以使用
#忽略關係先安裝一個包,然後安裝另一個包


        --replacepkgs: 重新安裝

[root@localhost Packages]# rpm -ivh --replacepkgs zsh-html-4.3.10-7.el6.x86_64.rpm 
Preparing...                ########################################### [100%]
   1:zsh-html               ########################################### [100%]
#注意事項:重新安裝可能存在新的配置文件覆蓋之前的配置文件。所以建議重新安裝前備份一下配置文件。

        

        --nosignature: 不檢查來源合法性

        --nodigest:不檢查包完整性

[root@localhost Packages]# rpm -ivh --nosignature --nodigest zsh-html-4.3.10-7.el6.x86_64.rpm 
Preparing...                ########################################### [100%]
	package zsh-html-4.3.10-7.el6.x86_64 is already installed
#由於rpm包是第三方爲我們提供的。所以爲了安裝的可靠性。在沒有導入官方密鑰的時候我們安裝是會有警告提示的

        

        --noscripts:不執行程序包腳本片斷,包含以下四個腳本

        --nopre: 安裝前腳本(例如安裝某個程序的時候,需要特定的用戶去安裝,而我們系統沒有此用戶,此時就需要寫一個安裝前腳本來創建此用戶,以便執行後面的程序包安裝)

        --nopost:安裝後腳本

        --nopreun:卸載前腳本

        --nopostun:卸載後腳本 

[root@localhost Packages]# rpm -ivh --test --noscripts --nopre --nopost --nopreun --nopostun 
#zsh-html-4.3.10-7.el6.x86_64.rpm 
Preparing...                ########################################### [100%]
	package zsh-html-4.3.10-7.el6.x86_64 is already installed
#以上命令沒有實際用途。一般添加需要忽略的腳本的參數即可。這裏只是提供測試。


②、RPM包的升級

rpm {-U|--upgrade} [install-options] PACKAGE_FILE ...

upgrage:安裝有舊版程序包,則“升級”;如果不存在舊版程序包,則“安裝”

rpm {-F|--freshen} [install-options] PACKAGE_FILE ...

freeshen:安裝有舊版程序包,則“升級”;如果不存在舊版程序包,則不執行升級

        -v: 顯示安裝過程

        -h: 以#顯示程序包管理執行進度;每個#表示2%的進度

[root@localhost Packages]# rpm -e zsh-html
[root@localhost Packages]# rpm -Fvh zsh-html-4.3.10-7.el6.x86_64.rpm 
[root@localhost Packages]# rpm -Uvh zsh-html-4.3.10-7.el6.x86_64.rpm 
Preparing...                ########################################### [100%]
   1:zsh-html               ########################################### [100%]
#這裏我們卸載zsh-html。然後使用rpm -Fvh進行升級。因爲不存在舊版程序包,所以不執行升級。
#而rpm -Uvh在不存在舊版程序包時,會對此程序包進行安裝。

        

        --oldpackage:降級;

        --force: 強行升級;


升級注意事項:如果原程序包的配置文件安裝後曾被修改,升級時,新版本的提供的同一個配置文件並不會直接覆蓋老版本的配置文件,而把新版本的文件重命名(FILENAME.rpmnew)後保留


③、RPM包的查詢

rpm {-q|--query} [select-options] [query-options]

    [select-options]

        -a: 查詢當前系統安裝的所有包

[root@localhost Packages]# rpm -qa
gnutls-2.8.5-18.el6.x86_64
setup-2.8.14-20.el6_4.1.noarch
........
libthai-0.1.12-3.el6.x86_64

       

        -f: 查看指定的文件由哪個程序包安裝生成

[root@localhost Packages]# rpm -qf /bin/bash
bash-4.1.2-15.el6_4.x86_64

        

        -p:針對尚未安裝的程序包文件做查詢操作

[root@localhost Packages]# rpm -qpl php-dba-5.3.3-26.el6.x86_64.rpm 
/etc/php.d/dba.ini
/usr/lib64/php/modules/dba.so
#rpm -qp可以配合[query-options]選項來查詢未安裝包的信息


        --whatrequires CAPABILITY:查詢指定的CAPABILITY被哪個包所依賴

[root@localhost Packages]# rpm -q --whatrequires /bin/bash
glibc-common-2.12-1.132.el6.x86_64
ca-certificates-2013.1.94-65.0.el6.noarch
........
groff-1.18.1.4-21.el6.x86_64

        

        --whatprovides CAPABILITY:查詢指定的CAPABILITY由哪個包所提供

[root@localhost Packages]# rpm -q --whatprovides /bin/bash
bash-4.1.2-15.el6_4.x86_64


    [query-options]

        --changelog:查詢rpm包的changlog。

[root@localhost Packages]# rpm -q --changelog zsh-html
* 一 8月 05 2013 James Antill <[email protected]> - 4.3.10-7
- Change {NAME:OFFSET:LENGTH} substitution feature to ignore KSH_ARRAYS option.
- Fixup tests.
- Resolves: rhbz#820530


        -c: 查詢程序的配置文件

[root@localhost Packages]# rpm -qc bash
/etc/skel/.bash_logout
/etc/skel/.bash_profile
/etc/skel/.bashrc


        -d: 查詢程序的文檔

[root@localhost Packages]# rpm -qd bash
/usr/share/doc/bash-4.1.2/COPYING
/usr/share/info/bash.info.gz
/usr/share/man/man1/..1.gz
........
/usr/share/man/man1/:.1.gz


        -i: information(包的名稱,版本,描述等信息)

[root@localhost Packages]# rpm -qi bash
Name        : bash                         Relocations: (not relocatable)
Version     : 4.1.2                             Vendor: CentOS
Release     : 15.el6_4                      Build Date: 2013年07月18日 星期四 21時21分24秒
Install Date: 2015年08月27日 星期四 14時53分45秒      Build Host: c6b10.bsys.dev.centos.org
Group       : System Environment/Shells     Source RPM: bash-4.1.2-15.el6_4.src.rpm
Size        : 3139291                          License: GPLv3+
Signature   : RSA/SHA1, 2013年07月18日 星期四 21時46分10秒, Key ID 0946fca2c105b9de
Packager    : CentOS BuildSystem <http://bugs.centos.org>
URL         : http://www.gnu.org/software/bash
Summary     : The GNU Bourne Again shell
Description :
The GNU Bourne Again shell (Bash) is a shell or command language
interpreter that is compatible with the Bourne shell (sh). Bash
incorporates useful features from the Korn shell (ksh) and the C shell
(csh). Most sh scripts can be run by bash without modification.


        -l: 查看指定的程序包安裝後生成的所有文件

[root@localhost Packages]# rpm -ql bash
/bin/bash
/bin/sh
/etc/skel/.bash_logout
........
/etc/skel/.bash_profile


        --scripts:程序包自帶的腳本片斷(這裏可以看到上面提到的四類腳本)

[root@localhost Packages]# rpm -q --scripts bash
postinstall scriptlet (using <lua>):
bashfound = false;
shfound = false;
f = io.open("/etc/shells", "r");
........
f:close()
postuninstall scriptlet (using /bin/sh):
if [ "$1" = 0 ]; then
    /bin/grep -v '^/bin/bash$' < /etc/shells | \
      /bin/grep -v '^/bin/sh$' > /etc/shells.new
    /bin/mv /etc/shells.new /etc/shells
fi


        -R: 查詢指定的程序包所依賴的CAPABILITY

[root@localhost Packages]# rpm -qR bash
/bin/sh  
/bin/sh  
config(bash) = 4.1.2-15.el6_4
........
libc.so.6()(64bit)


        --provides: 列出指定程序包所提供的CAPABILITY

[root@localhost Packages]# rpm -q --provides bash
config(bash) = 4.1.2-15.el6_4
bash = 4.1.2-15.el6_4
bash(x86-64) = 4.1.2-15.el6_4


④、RPM包的卸載

rpm {-e|--erase} [--allmatches] [--nodeps] [--noscripts][--notriggers] [--test] PACKAGE_NAME ...

[root@localhost Packages]# rpm -e zsh-html
#此時無聲勝有聲。沒有提示就是最好的提示,這樣代表卸載成功

注意:在卸載程序包時,如果此程序被其他包所依賴,則將依賴於此包的所有包一併卸載,或者,使用–nodpes選項忽略依賴關係;但是,依賴於此程序的程序包可能無法正常運行。


⑤、RPM包校驗

rpm {-V|--verify} [select-options] [verify-options]

[root@localhost Packages]# vim /etc/skel/.bash_logout
[root@localhost Packages]# rpm -V bash
S.5....T.  c /etc/skel/.bash_logout
#S.5....T. 每一位代表一個權限,請查看以下字段,通過查看權限位校驗判斷

S file Size differs(文件大小改變)

M Mode differs (includes permissions and file type)(權限改變)

5 digest (formerly MD5 sum) differs(MD5校驗改變)

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(能力、功能不匹配)


也可以指定一下參數來忽略校驗的選項。 

       --nodeps(不校驗依賴關係)

       --nofiles(不校驗包文件的任何屬性)

       --noscripts(不校驗腳本信息)

       --nofiledigest (formerly --nomd5)

       --nosize

       --nouser

       --nogroup

       --nomtime

       --nomode

       --nordev


⑥、包來源合法性及完整性驗正

    包來源合法性驗正及完整性驗正:

        完整性驗正:SHA256

        來源合法性驗正:RSA


    公鑰加密:

    對稱加密:加密、解密使用同一密鑰;

    非對稱加密:密鑰是成對兒的,

        public key: 公鑰,公開所有人

        secret key: 私鑰, 不能公開

wKioL1XjH13DkY4PAAEMI-FGh6o317.jpg

                        非對稱加密機制


如果是通過官方或合法途徑下載的鏡像文件,鏡像中都會提供使用非對稱加密計算出來的一個密鑰(RPM-GPG-KEY-CentOS-6),因爲Packages中的包都是用(RPM-GPG-KEY-CentOS-6)密鑰進行加密的,所以我們可以用(RPM-GPG-KEY-CentOS-6)來校驗rpm包的完整性。

[root@localhost mnt]# rpm --import RPM-GPG-KEY-CentOS-6

在生產環境中安裝不明來歷的RPM包是極具風險的。所以安裝有風險。以下提供可靠的RPM獲取方法:

    (1) 系統發版的光盤或官方的服務器;

        CentOS鏡像:

            http://mirrors.aliyun.com

            http://mirrors.sohu.com

            http://mirrors.163.com


    (2) 項目官方站點

    (3) 第三方組織:

        Fedora-EPEL

        搜索引擎:

            http://pkgs.org

            http://rpmfind.net

            http://rpm.pbone.net

    (4) 自己製作


⑦、RPM包的數據庫信息查詢和管理

[root@localhost rpm]# pwd
/var/lib/rpm
[root@localhost rpm]# ls
Basenames     __db.004     Name            Pubkeys         Triggername
Conflictname  Dirnames     Obsoletename    Requirename
__db.001      Filedigests  Packages        Requireversion
__db.002      Group        Providename     Sha1header
__db.003      Installtid   Provideversion  Sigmd5
#存儲程序包名稱及版本、依賴關係、功能說明、安裝生成的各文件的文件路徑及校驗碼信息
#Name(存放所有包名),Group(存放所有組),Conflictname(所有衝突關係),Requirename(包的依賴關係)等


當我們不小心誤刪除或此處文件有損壞的,就需要對數據庫進行重建(讀取每一個包的信息,然後進行重建)

rpm {--initdb|--rebuilddb}

    initdb: 初始化

        如果事先不存在數據庫,則新建之;否則,不執行任何操作;

    rebuilddb:重建

        無論當前存在與否,直接重新創建數據庫;


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章