rpm包管理
1. rpm包管理器概述
源碼到程式包的轉換過程
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCM581dvRWYoNHLwEzX5xCMx8FesU2cfdGLwATMfRHLGZkRGZkRfJ3bs92YskmNhVTYykVNQJVMRhXVEF1X0hXZ0xiNx8VZ6l2cssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnLzMzM2ITMyczM2cDM3YTNx8CX5IDOwkTMwIzLcNXZnFWbp9CXvwVbvNmLvR3YxUjL0M3Lc9CX6MHc0RHaiojIsJye.png)
rpm是Redhat公司針對自己的作業系統RHEL提出的一種管理軟體包的方法,rpm原來全稱為RedHat Package Manager,後來由于rpm包管理器的使用友善以及Redhat公司采取各種商業政策,使得rpm成為了工業标準,其他系統可借鑒使用rpm,是以rpm全稱後來改為:RPM Package Manager。在系統上隻要安裝了rpm包管理器,那麼隻要符合rpm标準的程式封包件都可以實作更為友善地安裝、更新、解除安裝和查詢等管理操作。
為什麼要使用rpm?
Linux的哲學思想之一是“一個程式隻做一件事,并且做好”。是以Linux經常通過使用衆多功能單一的程式來完成複雜任務,最常見的例子是管道指令的使用。而各個程式功能的單一,帶來的問題是各個程式檔案之間的産生了極大的依賴性,這是一個需要解決的問題。此外,要安裝各種功能的程式,而各程式在安裝時的路徑、生成的檔案各不相同,這給解除安裝某程式将帶來極×××煩,極不友善管理,以及對程式的版本的管理等。在Linux上隻要安裝rpm包管理器即可解決以上問題,rpm包管理器可将編譯好的各個應用程式組成檔案打包成一個或有限個rpm程式包,每個包中會記錄目前包的依賴性。一旦程式包安裝了之後,rpm會追蹤其各個檔案的安裝路徑(包括程式運作時産生的臨時檔案)。rpm包管理器就是通過這種方式來實作對rpm程式包的管理的,而對程式包的管理無外乎是安裝、更新、解除安裝、查詢等操作。
2. 程式包管理器的組成部分
程式包管理器由程式包組成清單和資料庫兩部分組成:
(1)程式包的組成清單(每個程式都單獨實作):
①檔案清單
②安裝或解除安裝時運作的腳本
(2)資料庫(為所有rpm程式包所共用):
①程式包的名稱和版本
②依賴關系
③功能說明
④安裝生成的各個檔案的檔案路徑及校驗碼資訊
3. rpm包命名格式
rpm包有主包和支包(主包的子包)之分,支包作為主包的功能性補充。其中rpm主包的命名格式為:name-VERSION-release.arch.rpm。各個部分解釋如下:
name:程式名
VERSION:版本
VERSION由三部分組成:
①major:程式的主版本号
②minor:程式的次版本号
③release:程式的修訂号
release[.os].arch:代表rpm包的發行号
①release[.os]:rpm版本+作業系統
②arch:archetecture,支援的硬體架構。常見的硬體架構有i386, x64(amd64), ppc, noarch(支援任何架構)等
各組成部分示意圖如下:
舉個例子,zsh-5.0.2-25.el7.x86_64.rpm代表:該zsh程式包的主版本号為5,次版本号為0,修訂号為2;rpm的版本号為25,支援的作業系統是RHEL 7(CentOS 7),支援的硬體架構是x86_64。
對于支包來說,其命名格式為:
name-function-VERSION-release.arch.rpm
常見的function有:devel, utils(工具程式), libs, ...
4. 擷取程式包的途徑
如何擷取rpm包呢?
(1)系統發行版的CD光牒或官方的檔案伺服器(或鏡像站點)
常見的鏡像網站如:
http://mirrors.aliyun.com
http://mirrors.sohu.com
http://mirrors.163.com
(2)項目的官方站點
(3)第三方組織
(3)第三方組織
(a)EPEL
(b)搜尋引擎
http://pkgs.org
http://rpmfind.net
http://rpm.pbone.net
...
(4)自己制作rpm包
建議:檢查其合法性(來源合法性、程式包的完整性)
5. CentOS系統上rpm指令管理程式包
5.1. 安裝
文法格式:
rpm {-i|--install} [install-options] PACKAGE_FILE ...
常用指令選項:
-v:verbose,輸出詳細的過程資訊;
-vv:very verbose,輸出更為詳細的過程資訊;
安裝選項(install-options):
-h:hash marks輸出進度條;hash标記符為#,每個#表示2%的進度;
--test:測試安裝,檢查并報告依賴關系及沖突資訊等;相當于dry run;
--nodeps:忽略依賴關系,不建議使用;
--replacepkgs:重新安裝;
--noscripts:指定不運作腳本;
--nosignature:不檢查包簽名資訊,即不檢查程式包的來源合法性;
--nodigest:不檢查包完整性資訊;
用法:
rpm -ivh PACKAGE_FILE ...
注意:rpm可以自帶腳本
最多有四類腳本:(--noscripts可指定不運作這四類腳本)
preinstall:安裝過程開始之前運作的腳本,%pre;--nopre可指定不運作;
postinstall:安裝過程完成之後運作的腳本,%post;--nopost可指定不運作;
preuninstall:解除安裝過程真正開始執行之前運作的腳本,%preun;--nopreun可指定不運作;
postuninstall:解除安裝過程完成之後運作的腳本,%postun;--nopostun可指定不運作;
指令示範:
安裝zsh,首先挂載CD光牒:
[root@osyunwei ~]# mkdir /media/cdrom
[root@osyunwei ~]# mount /dev/sr0 /media/cdrommount: block device /dev/sr0 is write-protected, mounting read-only
用rpm下載下傳zsh:
[root@osyunwei ~]# cd /media/cdrom/Packages/
[root@osyunwei Packages]# rpm -ivh zsh-4.3.11-4.el6.centos.2.x86_64.rpm Preparing... ########################################### [100%]
1:zsh ########################################### [100%]
5.2. 更新
rpm {-U|--upgrade} [install-options] PACKAGE_FILE ...
rpm {-F|--freshen} [install-options] PACKAGE_FILE ...
常用選項:
-U:更新或安裝;
-F:更新;
-v:同“安裝”;
-vv:同“安裝”.
--oldpackage:降級 --> 某些程式更新後遇到不相容的情況,此時需要降級;
--force:強制更新 --> 某些程式更新後會引起依賴性問題,此時可能會用到此選項;
其他安裝選項同“安裝”。
rpm -Uvh PACKAGE_FILE ...
rpm -Fvh PACKAGE_FILE ...
注意:
(1)Linux支援多核心版本并存,是以不要對核心做更新操作,因為這樣有可能會導緻無法“復原”,建議直接安裝新版本核心即可。
(2)如果某原程式包的配置檔案安裝後曾被修改過,則在更新時,新版本的程式提供的同一個配置檔案不會覆寫原有版本的配置檔案,而是把新版本的配置檔案重命名(FILENAME.rpmnew)後提供;
檢視目前已安裝的zsh的版本:
[root@osyunwei ~]# rpm -q zshzsh-4.3.11-4.el6.centos.2.x86_64
從網易鏡像站點下載下傳zsh-5.0.2-25.el7_3.1.x86_64.rpm程式包:
[root@osyunwei ~]# wget http://mirrors.163.com/centos/7/updates/x86_64/Packages/zsh-5.0.225.el7_3.1.x86_64.rpm
用rpm更新zsh:
[root@osyunwei ~]# rpm -Uvh zsh-5.0.2-25.el7_3.1.x86_64.rpm warning: zsh-5.0.2-25.el7_3.1.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5: NOKEY
error: Failed dependencies:
libc.so.6(GLIBC_2.14)(64bit) is needed by zsh-5.0.2-25.el7_3.1.x86_64
libc.so.6(GLIBC_2.15)(64bit) is needed by zsh-5.0.2-25.el7_3.1.x86_64
發現有依賴關系導緻無法更新。
此時若要強行更新可使用--nodeps選項:
[root@osyunwei ~]# rpm -Uvh --nodeps zsh-5.0.2-25.el7_3.1.x86_64.rpmwarning: zsh-5.0.2-25.el7_3.1.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5: NOKEY
Preparing... ########################################### [100%]
注意:忽略依賴性更新後程式不一定能正常運作!
再将zsh降級:
[root@osyunwei Packages]# rpm -Uvh --oldpackage zsh-4.3.11-4.el6.centos.2.x86_64.rpm Preparing... ########################################### [100%]
5.3. 解除安裝
rpm {-e|--erase} [--allmatches] [--nodeps] [--test] PACKAGE_NAME ...
解除安裝選項(erase options):
--allmatches:解除安裝所有比對指定名稱的程式包的各版本;
--nodeps:忽略依賴關系;
--test:測試解除安裝,dry run模式。
rpm -e PACKAGE_NAME
解除安裝已安裝的zsh程式包:
[root@osyunwei ~]# rpm -e zsh
如果沒有任何顯示就說明解除安裝成功了!
5.4. 查詢
rpm {-q|--query} [select-options] [query-options]
[select-options]:
PACKAGE_NAME:查詢指定的程式包是否安裝,及其版本;
-a, --all:查詢所有已經安裝過的包;
-f, --file FILE:查詢指定的檔案由哪個程式包安裝生成;
-p, --package PACKAGE_FILE:用于實作對未安裝的程式包執行查詢操作;
--whatprovides CAPABILITY:查詢指定的CAPABILITY由哪個程式包提供;
--whatrequires CAPABILITY:查詢指定的CAPABILITY被哪個包所依賴。
[query-options]:
--changelog:查詢rpm包的changelog;
-i, --info:程式包相關的資訊,版本号、大小、所屬的包組等
-l, --list:程式包安裝生成的所有檔案清單;
-c, --configfiles:查詢指定的程式包提供的配置檔案;
-d, --docfiles:查詢指定的程式包提供的文檔;
--provides:列出指定的程式包提供的所有的CAPABILITY;
-R, --requires:查詢指定的程式包的依賴關系;
--scripts:檢視程式包自帶的腳本片段。
rpm -qi PACKAGE
rpm -qf FILE
rpm -qc PACKAGE
rpm -qd PACKAGE
rpm -qpi PACKAGE_FILE
rpm -apl PACKAGE_FILE
rpm -qpc PACKAGE_FILE
列了這麼多個選項,不如來個執行個體吧!
(1)檢視zsh是否已經安裝:
[root@osyunwei ~]# rpm -qa | grep '^zsh'zsh-4.3.11-4.el6.centos.2.x86_64 //顯示已安裝zsh;
或:[root@osyunwei ~]# rpm -q zshzsh-4.3.11-4.el6.centos.2.x86_64 //顯示已安裝zsh;
(2)查詢/etc/fstab由哪個程式包安裝生成:
[root@osyunwei ~]# rpm -qf /etc/fstab setup-2.8.14-20.el6_4.1.noarch
(3)列出安裝httpd生成的所有檔案清單:
[root@osyunwei ~]# rpm -ql httpd
(4)列出httpd程式包的依賴關系:
[root@osyunwei ~]# rpm -qR httpd/bin/bash
/bin/sh
.....(省略).....
libz.so.1()(64bit) rpmlib(CompressedFileNames) <= 3.0.4-1.....(省略).....
rpmlib(VersionedDependencies) <= 3.0.3-1
rtld(GNU_HASH) system-logos >= 7.92.1-1
rpmlib(PayloadIsXz) <= 5.2-1
(5)檢視httpd程式包提供的文檔:
[root@osyunwei ~]# rpm -qd httpd/usr/share/doc/httpd-2.2.15/ABOUT_APACHE
/usr/share/doc/httpd-2.2.15/CHANGES
/usr/share/doc/httpd-2.2.15/LICENSE
/usr/share/doc/httpd-2.2.15/NOTICE
/usr/share/doc/httpd-2.2.15/README
/usr/share/doc/httpd-2.2.15/VERSIONING
/usr/share/man/man8/apachectl.8.gz
/usr/share/man/man8/htcacheclean.8.gz
/usr/share/man/man8/httpd.8.gz
/usr/share/man/man8/rotatelogs.8.gz
/usr/share/man/man8/suexec.8.gz
(6)查詢httpd程式包提供的配置檔案:
[root@osyunwei ~]# rpm -qc httpd/etc/httpd/conf.d/welcome.conf
/etc/httpd/conf/httpd.conf
/etc/httpd/conf/magic
/etc/logrotate.d/httpd
/etc/sysconfig/htcacheclean
/etc/sysconfig/httpd
/var/www/error/HTTP_BAD_GATEWAY.html.var
/var/www/error/HTTP_BAD_REQUEST.html.var.....(以下省略).....
(7)檢視httpd程式包自帶的腳本片段:
[root@osyunwei ~]# rpm -q --scripts httpd
(8)列出bash程式包提供的所有的CAPABILITY:
[root@osyunwei ~]# rpm -q --provides bashconfig(bash) = 4.1.2-40.el6bash = 4.1.2-40.el6
bash(x86-64) = 4.1.2-40.el6
(9)檢視httpd程式包提供的所有的CAPABILITY:
[root@osyunwei ~]# rpm -q --provides httpdconfig(httpd) = 2.2.15-53.el6.centos
httpd-mmn = 20051115
httpd-suexec = 2.2.15-53.el6.centos.....(中間省略).....
mod_vhost_alias.so()(64bit) webserver
.....(以下省略).....
(10)查詢指定的CAPABILITY (這裡為webserver)由哪個程式包提供:
[root@osyunwei ~]# rpm -q --whatprovides webserverhttpd-2.2.15-53.el6.centos.x86_64
(11)查詢指定的CAPABILITY (這裡為bash)被哪個包所依賴:
[root@osyunwei ~]# rpm -q --whatrequires bashjline-0.9.94-0.8.el6.noarch
initscripts-9.03.53-1.el6.centos.x86_64
dracut-004-409.el6.noarch
lvm2-2.02.143-7.el6.x86_64
rsyslog-5.8.10-10.el6_6.x86_64
cronie-1.4.4-15.el6_7.1.x86_64
autofs-5.0.5-122.el6.x86_64
eclipse-pde-3.6.1-6.13.el6.x86_64
(12)檢視bash的更新日志(changelog):
[root@osyunwei ~]# rpm -q --changelog bash...
* Fri Oct 17 1997 Donnie Barnes <[email protected]>- added BuildRoot
* Tue Jun 03 1997 Erik Troan <[email protected]>- built against glibc
(13)檢視程式包相關的資訊,版本号、大小、所屬的包組等:
[root@osyunwei ~]# rpm -qi zsh
5.5. 校驗
用途:可檢查程式包中的資料是否被修改過。
rpm {-V|--verify} [select-options] [verify-options]
rpm -V PACKAGE_NAME
校驗屬性:
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
修改zsh程式包的配置檔案,首先檢視zsh程式包的配置檔案有哪些:
[root@osyunwei ~]# rpm -qc zsh/etc/skel/.zshrc
/etc/zlogin
/etc/zlogout
/etc/zprofile
/etc/zshenv
/etc/zshrc
用vim修改/etc/zshrc檔案,在首行添加一個'#'字元,然後再用-V選項檢驗:
[root@osyunwei ~]# vim /etc/zshrc
[root@osyunwei ~]# rpm -V zshS.5....T. c /etc/zshrc
顯然,檔案/etc/zshrc的大小、md5值、時間戳(mtime)發生了變化。
5.6. 資料庫重建
預設rpm管理器的資料庫路徑為/var/lib/rpm,剛才的查詢操作正是通過此處的資料庫進行。
擷取幫助:
CentOS 6:man rpm
CentOS 7:man rpmdb
rpm {--initdb|--rebuilddb} [-v] [--dbpath DIRECTORY] [--root DIRECTORY]
--initdb:初始化資料庫,目前無任何資料庫可初試化建立一個新的資料庫;目前有時不執行任何操作;
--rebuilddb:重新建構,通過周遊讀取目前系統上所有已經安裝過的程式包進行重新建立;
在/tmp/mydb目錄下建立初始化資料庫:
[root@osyunwei ~]# rpm --initdb --dbpath /tmp/mydb[root@osyunwei ~]# ls /tmp/mydb/__db.001 __db.002 __db.003 __db.004 Packages
在/tmp/mydb目錄下重新建立資料庫:
[root@osyunwei ~]# rpm --rebuilddb --dbpath /tmp/mydb[root@osyunwei ~]# ls /tmp/mydb/Packages
注意:不一定能夠重建完整的資料庫,是以慎用該指令吧!
5.7. 包來源合法性驗證和完整性驗證
首先要了解一下什麼是數字簽名?
數字簽名就是用本地密鑰去加密對應資料的特征碼。
程式包開發者将程式包制作好之後,采用單向加密算法對程式包進行計算,得到定長特征碼,再用私鑰對這段定長特征值進行加密,并将加密過的特征碼附于程式包尾部,這就是數字簽名。程式使用者先得到開發者的公鑰,用于解密特征碼,如果解密成功,說明來源合法;然後使用者在本地對該程式包用單向加密算法再次計算出定長特征碼,如果使用者計算出的特征碼和程式開發者提供的特征碼相同,則說明程式資料完整。雖然用了兩種加密算法,但卻沒有保密性的概念,而是作為驗證。
特征碼有沒有被篡改的可能性?假設中間人得到程式包的特征值後,想篡改特征碼,但篡改後需要用本地私鑰進行加密,是以來源就不合法了,更不用談完整性了,是以特征碼是無法修改的。
但存在一個問題,就是使用者如何獲得正确的公鑰?這要求下載下傳公鑰的網站的正确性以及資料在網絡傳輸過程中的安全性,涉及網絡安全問題。
圖解數字簽名 :
對于CentOS發行版來說,假設已擷取正确的公鑰,那麼導入信任的包制作者的公鑰(或簽名密鑰)操作如下:
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
兩種驗證方式:
(1)安裝此組織簽名的程式時,程式内部會自動執行驗證。
(2)手動驗證:rpm -K PACKAGE_FILE,同樣由程式内部自行執行校驗操作。
校驗zsh程式包的來源合法性及資料完整性:
[root@osyunwei Packages]# rpm -K zsh-4.3.11-4.el6.centos.2.x86_64.rpm zsh-4.3.11-4.el6.centos.2.x86_64.rpm: rsa sha1 (md5) pgp md5 OK //校驗通過;