Linux 基礎 —— RPM


http://liaoph.com/linux-rpm/

這篇文章主要講 RPM 軟件包管理器的使用。

軟件包的演變史

最早期時,軟件包是一些可以運行的程序組成的集合,可能還要加上若干配置文件和動態庫。例如,程序員將針對某個平台編譯好的二進制文件、程序所依賴的動態庫文件(如 .so 和 .dll 為擴展名的文件)以及配置文件復制到一個目錄中,這個目錄就可以稱為一個軟件包。

為了保證使用的軟件包能夠方便且快速地復制到別的機器上, 人們開始選用壓縮文件的方式來封裝軟件包。 比如通過 tar 或者 gzip 壓縮后得到 .tar.gz、 .rar 或者 .zip 格式的文件, 這時我們就獲得了一個較為高級的軟件包。

再往后發展, 就出現了更高級的軟件包, 比如 .rpm、 .bin 或者 .deb 格式的軟件包。 這些格式的軟件包, 相對於壓縮格式的軟件包又有了更進一步的發展, 它們不僅支持文件壓縮功能, 還有依賴維護、 腳本的嵌入等功能。RedHat 公司開發貢獻的 RedHat Package Manager(RPM) 可以說是這些高級別軟件包中最典型的一個。

RPM 軟件包的功能

RPM 軟件包的功能如下:

  • 存儲和數據壓縮
  • 文件安裝
  • 配置文件生成
  • 系統服務注冊
  • 軟件依賴檢查和依賴輸出

存儲數據壓縮

RPM具有軟件包的基本功能——數據壓縮存儲,RPM 安裝列表中的文件在按照某個指定的算法(如 gzip)壓縮后,作為最終 RPM 文件的一個數據塊,與其他控制信息存儲進同一個文件中。最終所有的數據都存儲在同一個 RPM 文件中。

文件安裝

文件安裝是軟件包的一個基本功能,它將壓縮的文件解壓至目標操作系統上。安裝過程中,還可能動態生成一些文件,並安裝到系統中。

配置文件生成

配置文件既可能是預先寫好的靜態文件,也可能是根據安裝環境動態生成的文件。

系統服務注冊

使用 rpm 安裝一些軟件包,比如 apachemysql-server 等,在安裝完成后,目錄 /etc/init.d/下會生成一個服務啟動腳本文件,而且此服務還可能被加入到系統的自動啟動服務中。

軟件依賴檢查

大多數程序都會依賴其他組件,比如數據庫操作程序可能需要 libmysql 的支持。為了保證每個軟件在安裝后都能正常運行,在安裝過程中,軟件安裝程序需要對該軟件包所依賴的所有元素進行檢查。

其他功能

RPM 還有一個重要功能就是對嵌入腳本的支持:它支持在安裝軟件或者卸載軟件的過程中,執行用戶預定義的指令。常用的腳本執行點如下:

  • pre install
  • post install
  • pre uninstall
  • post uninstall

pre/post install 表示在安裝之前或之后;pre/post uninstall 表示在卸載之前或者之后。

除此之外,RPM 包還可以支持對源包進行數字簽名,在安裝時可以使用公鑰驗證 RPM 包的合法性等等。

RPM 包的命名方式

以 httpd-2.2.15-39.el6.centos.x86_64.rpm 為例,這里 httpd 表示軟件名,2.2.15 表示主版本號,次版本號,發行版本號分別是221539.el6.centos 表示 RPM 包的修訂號和 OS 信息,x86_64 表示此軟件包適用的平台,常見的有i386i586x86_64 等等。

RPM 包管理命令的使用

安裝

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

安裝時可以使用 -h 顯式安裝進度,使用 -v 顯示詳細信息。

[root@localhost ~]# rpm -ivh httpd-2.2.15-39.el6.centos.x86_64.rpm Preparing... ########################################### [100%] 1:httpd ########################################### [100%]

使用 --test 可以用於測試安裝是否能夠成功,而不實際安裝。

在安裝過程中,可能遇到軟件包的依賴問題,而需要先安裝其他軟件包,這時可以使用 --nodeps 忽略依賴強制安裝,但是這樣安裝的軟件包通常也會因為依賴缺失而無法正常工作。

如果需要重新安裝並覆蓋原有的文件,可以使用 --replacepkgs 選項。

使用 --force 可以進行強制覆蓋安裝,它等同於--replacepkgs, --replacefiles, 和 --oldpackage

升級

升級或安裝

如果不知道一個軟件包是否已經安裝,並希望如果已經安裝那么升級次軟件包,使用 -U 選項。

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

如果僅僅希望升級軟件包,使用 -F 選項

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

升級軟件包和安裝軟件包一樣,可以使用 --test--nodeps--force 等選項。

示例:安裝並升級 zsh 軟件包

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

如果想要將軟件包降級到舊版本,使用 --oldpackage 選項

[root@localhost rpm]# rpm -Uvh --oldpackage zsh-4.3.10-7.el6.x86_64.rpm Preparing... ########################################### [100%] 1:zsh ########################################### [100%]

在升級軟件包時,原來軟件包的配置文件可能已經被修改,升級時,新版本的文件不會將老版本的配置文件覆蓋,而是將新版本的配置文件加上 .rpmnew 后綴后保存。

注意:內核也是軟件包,但是不要直接對內核進行升級(如果新的內核有兼容問題啟動不了而舊內核又被覆蓋就悲劇了),因為 Linux 允許多內核共存,所以可以直接安裝多個不同版本內核。

卸載

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

通常使用 rpm -e PACKAGE_ANEM 即可簡單卸載一個軟件包。

使用 --nodeps 忽略依賴關系。--test 測試卸載。--allmatches 表示如果一個程序包同時安裝多個版本,則次選項一次全部卸載之。

如果卸載正常,不會輸出任何信息。

注意:如果程序包的配置文件安裝后曾被修改,卸載時,此文件通常不會被刪除,而是被重命名為 .rpmsave 后綴后留存。

查詢:

查詢使用 -q 選項,可以檢查安裝的所有包,還可以查看某包的詳細信息。

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

查詢某包是否已經安裝

rpm -q PACKAGE_NAME...

如:

[root@localhost rpm]# rpm -q zsh zsh-4.3.10-9.el6.x86_64

查詢安裝的所有包

rpm -qa

查詢未安裝包的信息

在 -q 同時使用 -p 選項

注意:查詢未安裝包的信息指定的是 RPM 包的文件名而不是某個包的軟件名。

查詢選項

查詢某包的簡要說明信息

rpm -qi PACKAGE_NAME

如:

[root@localhost rpm]# rpm -qi zsh Name : zsh Relocations: (not relocatable) Version : 4.3.10 Vendor: CentOS Release : 9.el6 Build Date: Wed 05 Nov 2014 07:20:52 PM CST Install Date: Sat 11 Apr 2015 11:37:12 PM CST Build Host: c6b8.bsys.dev.centos.org Group : System Environment/Shells Source RPM: zsh-4.3.10-9.el6.src.rpm Size : 5009102 License: BSD Signature : RSA/SHA1, Wed 05 Nov 2014 08:05:42 PM CST, Key ID 0946fca2c105b9de Packager : CentOS BuildSystem <http://bugs.centos.org> URL : http://zsh.sunsite.dk/ Summary : A powerful interactive shell Description : The zsh shell is a command interpreter usable as an interactive login shell and as a shell script command processor. Zsh resembles the ksh shell (the Korn shell), but includes many enhancements. Zsh supports command line editing, built-in spelling correction, programmable command completion, shell functions (with autoloading), a history mechanism, and more.

這里顯式了 zsh 這個包的各類元信息,如名字,版本,發行商,打包作者,描述信息等。

查詢軟件包安裝的文件列表

rpm -ql PACKAGE_NAME

如:

[root@localhost rpm]# rpm -ql zsh /bin/zsh /etc/skel/.zshrc /etc/zlogin /etc/zlogout /etc/zprofile /etc/zshenv /etc/zshrc /usr/lib64/zsh /usr/lib64/zsh/4.3.10 ... /usr/share/zsh/4.3.10/functions/zstyle+ /usr/share/zsh/4.3.10/scripts /usr/share/zsh/4.3.10/scripts/newuser /usr/share/zsh/site-functions

使用 rpm -qc PACKAGE_NAME 可以查看軟件包安裝后生成的所有配置文件。

使用 rpm -qd PACKAGE_NAME 可以查看軟件包安裝后生成的所有說明文件和幫助文件。

查看軟件包制作時隨版本變化的 changelog 信息

rpm -q --changelog PACKAGE_NAME

查看軟件包提供的 capabilities (即輸出給其他軟件包的依賴)

rpm -q --provides PACKAGE_NAME

查看軟件包所需的依賴

rpm -q --requires PACKAGE_NAME

查看軟件包安裝或卸載時執行的腳本

rpm -q --scripts PACKAGE_NAME

如:

[root@localhost rpm]# 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

這里包含了安裝后,卸載前/后腳本。

檢驗

還可以查詢軟件包安裝之后的文件是否發生了改變

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

如:

[root@localhost rpm]# rpm -V httpd S.5....T. c /etc/httpd/conf/httpd.conf

檢驗時使用了多個位表示文件的多個屬性是否發生了變化:

S 文件大小 M 文件權限 5 文件摘要信息(通常是 MD5 碼) D 設備文件的主/次設備號 L 軟鏈接變化 U 屬主 G 屬組 T 文件的 mtime P caPabilities

程序包的合法性驗證

在軟件包制作時,為了防止軟件包被人修改植入后門,制作者可以使用自己私鑰對軟件包進行數字簽名,安裝者就可以使用公鑰驗證軟件包的合法性。同時還可以使用摘要算法提取軟件包的摘要信息用於驗證軟件包的完整性。

通常,RHEL 系的安裝光盤中包含有用於驗證其軟件包合法性的公鑰文件。

導入公鑰

rpm --import /path/to/RPM-GPG-KEY-FILE

驗證合法性

rpm {-K|--checksig} PACKAGE_FILE

RPM 管理器的數據庫

每次安裝 rpm 包時,rpm 系統會將一些元信息存儲在它的數據庫中,使用 rpm -q 命令查詢軟件包的相關信息時將會查詢這些數據庫,數據庫文件位於 /var/lib/rpm 目錄中。如果 RPM 的數據庫損壞,將會導致一些 RPM 數據丟失,一些功能將無法正常使用。

[root@bogon ~]# file /var/lib/rpm/* /var/lib/rpm/Basenames: Berkeley DB (Hash, version 9, native byte-order) /var/lib/rpm/Conflictname: Berkeley DB (Hash, version 9, native byte-order) /var/lib/rpm/__db.001: Applesoft BASIC program data /var/lib/rpm/__db.002: 386 pure executable /var/lib/rpm/__db.003: 386 pure executable not stripped /var/lib/rpm/__db.004: 386 pure executable /var/lib/rpm/Dirnames: Berkeley DB (Btree, version 9, native byte-order) /var/lib/rpm/Filedigests: Berkeley DB (Hash, version 9, native byte-order) /var/lib/rpm/Group: Berkeley DB (Hash, version 9, native byte-order) /var/lib/rpm/Installtid: Berkeley DB (Btree, version 9, native byte-order) /var/lib/rpm/Name: Berkeley DB (Hash, version 9, native byte-order) /var/lib/rpm/Obsoletename: Berkeley DB (Hash, version 9, native byte-order) /var/lib/rpm/Packages: Berkeley DB (Hash, version 9, native byte-order) /var/lib/rpm/Providename: Berkeley DB (Hash, version 9, native byte-order) /var/lib/rpm/Provideversion: Berkeley DB (Btree, version 9, native byte-order) /var/lib/rpm/Pubkeys: Berkeley DB (Hash, version 9, native byte-order) /var/lib/rpm/Requirename: Berkeley DB (Hash, version 9, native byte-order) /var/lib/rpm/Requireversion: Berkeley DB (Btree, version 9, native byte-order) /var/lib/rpm/Sha1header: Berkeley DB (Hash, version 9, native byte-order) /var/lib/rpm/Sigmd5: Berkeley DB (Hash, version 9, native byte-order) /var/lib/rpm/Triggername: Berkeley DB (Hash, version 9, native byte-order)

可以看到這里有很多 Berkeley DB 格式的數據庫文件和幾個 __db 數據文件。

重建數據庫

如果 RPM 的數據庫損壞,首先可以嘗試重建它,如果無法重建,那么需要重新初始化數據庫。

rpm --rebuilddb 表示重建數據庫

這個命令會從已安裝的軟件包提取信息重建數據庫,它從 /var/lib/rpm/Packages 這個文件中提取信息,其他所有的數據庫文件都可以由這個文件重建。如果 RPM 的數據庫是完好的,這個命令不會重建,而是對數據庫中未使用的條目進行空間回收。

rpm --initdb 創建一個新的 RPM 數據

如果已經沒有其他別的辦法了,--initdb 會創建一個新的空的 RPM 數據庫。由於新建的數據庫是空的,不要萬不得已不要使用這個命令。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM