本文大部分內容來自鳥哥的Linux私房菜,並且由作者根據自己的學習情況做了一些更改, "鳥哥原文鏈接" 1. 程式的安裝方式 1. 源代碼安裝:利用廠商釋出的Tarball 來進行軟體的安裝,每次安裝程式都需要檢測系統與環境、設定編譯參數、實際的編譯、 最後還要依據個人喜好的方式來安裝軟體到指定位置 ...
本文大部分內容來自鳥哥的Linux私房菜,並且由作者根據自己的學習情況做了一些更改,鳥哥原文鏈接
1. 程式的安裝方式
- 源代碼安裝:利用廠商釋出的Tarball 來進行軟體的安裝,每次安裝程式都需要檢測系統與環境、設定編譯參數、實際的編譯、 最後還要依據個人喜好的方式來安裝軟體到指定位置。這過程很麻煩。
- 程式包安裝:由軟體開發者先在他們的系統上面編譯好了使用者所需要的軟體,然後將這個編譯好的可執行的軟體發給使用者來安裝。而且在安裝的時候還可以加上一些與這些軟體相關的信息,將它建立成為資料庫,之後就可以進行安裝、卸載、 升級、查詢與驗證等等的相關功能。
2. 程式包管理器
源代碼-->目標二進位格式(包括二進位程式、程式自己的庫文件、配置文件、幫助文件)(C語言的話就是編譯好的可直接運行的C代碼)-->(把二進位程式、程式自己的庫文件、配置文件、幫助文件)組織成為一個或有限幾個“包”文件;
實現:安裝、升級、卸載、查詢、校驗;
在這個軟體包內還包含了預先檢測系統與依賴關係的腳本,該軟體會提供的所有文件信息等。最終將這個軟體發佈出來。用戶端取得這個文件後,只要通過特定的命令來安裝,那麼該軟體就會依照內部的腳本來檢測依賴的軟體是否存在,若安裝的環境符合需求,就會開始安裝,安裝完成後還會將該軟體的信息寫入程式管理機制中,以達成未來可以進行升級、移除等動作。
- Debian:dpt(Debian Packet Tool),dpgk(命令行工具)以“.deg”為尾碼
- Redhat:Redhat Package Manager, 簡稱rpm,這種方式是借鑒於debian的,以“.rpm”為尾碼,最開始用prel寫的,但是因為prel是腳本語言,效率太低,後改用C重新寫了。最終成為了標準,被重命名為RPM is Package Manager
- S.u.S.E:使用Redhat的RPM,以“.rpm”為尾碼,管理前端也叫rpm,但是研發出來一個更好的rpm庫。最後Redhat在將RPM推為標準的時候,將這個庫也用了。
- Gentoo:Ports,程式包管理,採用了Free BSD的方式。
- ArchLinux:新貴,研發了更好的程式包管理方式。
RPM優點
- RPM內含已經編譯過的程式與配置文件等信息,可以讓使用者免除重新編譯的困擾;
- RPM在被安裝之前,會先檢查系統的硬碟容量、系統版本等,可避免文件被錯誤安裝;
- RPM文件本身提供軟體版本信息、依賴軟體名稱、軟體用途說明、軟體所含文件等信息,便於瞭解軟體;
- RPM管理的方式使用資料庫庫記錄RPM文件的相關參數,便於升級、移除、查詢與驗證。
3. 什麼是RPM與SRPM
RPM:Redhat Packet Manager
RPM是以一種資料庫記錄的方式來將你所需要的軟體安裝到你的Linux系統的一套管理機制。
它最大的特點就是將你要安裝的軟體先編譯過, 並且打包成為RPM機制的包,通過RPM包裡頭預設的資料庫,記錄這個軟體安裝的時候必須具備的依賴軟體,當安裝在你的Linux主機時, RPM會先依照軟體裡頭的信息查詢當前Linux主機的是否有安裝依賴軟體, 若滿足則予以安裝,若不滿足則不予安裝。那麼安裝的時候就將該軟體的信息整個寫入RPM的資料庫中,以便未來的查詢、驗證與卸載等操作,這樣一來的優點是:
- 由於已經編譯完成並且打包完畢,所以軟體傳輸與安裝上很方便(不需要再重新編譯);
- 由於軟體的信息都已經記錄在Linux主機的資料庫上,很方便查詢、升級與卸載等操作;
當這樣造成了一些困擾:RPM包是應編譯好的軟體,所以只能在同樣的編譯環境中運行。也就是說,安裝這個軟體的系統必須要與當初編譯這個軟體的主機環境相同。舉例來說,rp-pppoe這個軟體必須要在ppp軟體存在的環境中安裝,如果系統尚不存在,就無法安裝(可以強制安裝,但是通常會出現問題)
軟體管理機制的問題是:
- 軟體安裝的環境必須與打包時的環境需求一致或相當;
- 需要滿足軟體的依賴性需求;
- 卸載時需要特別小心,最底層的軟體不可先移除,否則可能造成整個系統的問題!
SRPM:Source Redhat Packet Manager
這個SRPM所提供的軟體內容並沒有經過編譯,它提供的是原始碼!
通常SRPM的副檔名是以***.src.rpm這種格式來命名的。不過,既然SRPM提供的是原始碼,那麼為什麼我們不使用Tarball直接來安裝就好了?這是因為SRPM雖然內容是原始碼,但是他仍然含有該軟體所依賴的軟體說明、以及所有RPM文件所提供的信息。同時,他與RPM不同的是,他也提供了參數配置文件(就是configure與makefile)。所以,如果我們下載的是SRPM ,那麼要安裝該軟體時,就必須要:
- 先將該軟體以RPM 管理的方式編譯,此時SRPM會被編譯成為RPM文件;
- 然後將編譯完成的RPM文件安裝到Linux 系統當中
這樣雖然很麻煩,但好處是:可以通過修改SRPM內的參數配置文件,然後重新編譯產生能適合我們Linux環境的RPM包。
Tips:為何說CentOS是社群維護的企業版呢?Red Hat 公司的RHEL發佈後,連帶會將SRPM發佈。社群的朋友就將這些SRPM收集起來並重新編譯成為所需要的軟體,而CentOS就是這麼來的,所以才能號稱與 Red Hat 的RHEL企業版同步!
4. rpm包命名格式
name-VERSION-release.平臺架構.rpm
- name:軟體名稱
- VERSION:major.mirror
- release:通常就是編譯的次數
- 平臺架構:不一定總是為arch,也有可能是其他內容,這代表硬體平臺/平臺架構( i386,x64(amd64),ppc,noarch.......... )
- 例如:redis-3.0.2-1.centos7.x64.rpm
- 有的時候也會是這種格式:name-VERSION-release.os.平臺架構.rpm ##這其中os代表是系統;
拆包
把一個包當中的多種功能拆分,實現按需安裝(完整的包,功能太多了,有的用不上,如果全部安裝的話,一是占用空間,二是消耗資源)
- 主包:name-VERSION-release.平臺架構.rpm
- 支包(分包):name-function-VERSION-release.硬體平臺.rpm
例如
- dhcp-4.2.5-58.el7.centos.x86_64.rpm
- dhcp-common-4.2.5-58.el7.centos.x86_64.rpm ##命令
- dhcp-libs-4.2.5-58.el7.centos.x86_64.rpm ##庫
5. 獲取rpm程式包的途徑
1. 系統發行版的光碟或官方的文件伺服器(或鏡像站點)
http://mirrors.aliyun.com
http://mirrors.163.com
2. 項目的官方站點
http://repo.zabbix.com
3. 第三方組織
epel
- http://mirrors.aliyun.com/epel/
搜索引擎
- http://pkgs.org
- http://rpmfind.net
- http://rpm.phone.net
4. 自己編譯並封裝成RPM包
6. rpm命令
6.1 查詢
SYNOPSIS
rpm {-q|--query} [select-options] [query-options]
OPTIONS
select-options
[PACKAGE_NAME] [-a,--all] [-f,--file FILE]
[-g,--group GROUP] {-p,--package PACKAGE_FILE]
[--hdrid SHA1] [--pkgid MD5] [--tid TID]
[--querybynumber HDRNUM] [--triggeredby PACKAGE_NAME]
[--whatprovides CAPABILITY] [--whatrequires CAPABILITY]
query-options
[--changelog] [-c,--configfiles] [--conflicts]
[-d,--docfiles] [--dump] [--filesbypkg] [-i,--info]
[--last] [-l,--list] [--obsoletes] [--provides]
[--qf,--queryformat QUERYFMT] [-R,--requires]
[--scripts] [-s,--state] [--triggers,--triggerscripts]
-q:查詢
[select-options]:
-a:查詢所有安裝過的包;(可以對結果做grep,匹配想要的內容)
-f:查詢指定文件由哪個rpm包安裝生成的;
-g:查詢指定包組中包含的程式包;
-p:對未安裝的程式包查詢,這個rpm包可能在FTP或者HTTP上的URL上,通過指定[query-options],和rpm包,查詢未安裝程式的信息;
--whatprovides CAPABILITY:查詢指定的capability由哪個程式包提供(結合query-options選項);
--whatrequires CAPABILITY:查詢指定的capability被哪個程式包依賴(結合query-options選項);
[query-options]:
-l:查看程式安裝之後會產生的所有文件列表;
-i:查看程式包相關的信息,版本號,大小,所屬的包組,等;
-c:查詢指定程式包的安裝之後會產生的配置文件;
-d:查詢指定程式包的安裝之後提供的文檔;
-R:查詢指定程式包的依賴關係;
--provides:查看指定程式包提供的所有capability;
--scripts:查看程式包自帶的腳本片段(運行前、運行後、卸載前、卸載後);
--changelog:查看rpm包的更改日誌(是如何演進的);
用法
rpm -qi PACKAGE 查詢指定rpm包的信息
rpm -qf FILE 查詢指定文件是哪個rpm包生成的
rpm -qc PACKAGE 查詢指定rpm包產生了哪些/etc下的配置文件
rpm -ql PACKAGE 查詢指定rpm包生成的文件列表
rpm -qd PACKAGE 查詢指定rpm包提供的文檔
rpm -qpl PACKAGE_FILE 查詢未安裝的rpm包,在安裝之後會生成哪些文件
rpm -qpi PACKAGE_FILE 查詢未安裝的rpm包的信息
rpm -qpc PACKAGE_FILE 查詢未安裝的rpm包會提供哪些/etc下的配置文件
rpm -qp --scripts PACKAGE_FILE 查詢未安裝的rpm包,自帶的腳本片段
rpm -qf --changelog FILE 查看指定文件是哪個rpm包產生的,並顯示該rpm的演進信息
rpm -q --whatrequires bash 指定的capability被哪個程式包依賴;
rpm -q --whatprovides 'config(bash)' 指定的capability是那個程式包提供的;
rpm -q -R zsh 查詢指定rpm包的依賴關係;
rpm -q --scripts zsh 查詢指定rpm包自帶的四類腳本程式代碼;
Note:
要特別說明的是,在查詢本機上面的RPM軟體相關信息時, 不需要加上版本的名稱,只要加上軟體名稱即可!因為它會到/var/lib/rpm這個資料庫裡面去查詢, 所以我們可以不需要加上版本名稱。但是查詢某個RPM文件就不同了,我們必須要列出整個文件的完整檔名才行
FILE:表示文本文件的名稱; ##rpm -qf /bin/zsh
PACKAGE:表示rpm包名稱; ##rpm -qi zsh
PACKAGE_FILE:表示rpm包的完整名; ##rpm -qpi zsh-5.0.2-28.el7.x86_64.rpm
6.2 安裝
SYNOPSIS
rpm {-i|--install} [install-options] PACKAGE_FILE ...
INSTALL-OPTIONS
install-options
[--allfiles] [--badreloc] [--excludepath OLDPATH]
[--excludedocs] [--force] [-h,--hash]
[--ignoresize] [--ignorearch] [--ignoreos]
[--includedocs] [--justdb] [--nocollections]
[--nodeps] [--nodigest] [--nosignature] [--noplugins]
[--noorder] [--noscripts] [--notriggers]
[--oldpackage] [--percent] [--prefix NEWPATH]
[--relocate OLDPATH=NEWPATH]
[--replacefiles] [--replacepkgs]
[--test]
-i:install的意思
[install-options]
-h, --hash:輸出進度條,一共50個#,每個#進度表示2%;
--test:測試安裝,檢查並報告依賴關係及衝突消息等,dry run模式;
--nodeps:忽略依賴關係(安裝後使用可能有問題),不建議;
--replacepkgs:覆蓋安裝,即使已經安裝在這個系統上了(可以用來覆蓋配置文件);
--replacefiles:重新安裝某個已經安裝過的軟體;
--oldpackage:允許降級,舊包替換新包;
--force:具有--replacepkgs、--replacefiles、--oldpackage的功能;
--justdb:僅更新資料庫(由於RPM資料庫破損或者是某些緣故產生錯誤時,可使用這個選項來更新軟體在資料庫內的相關信息);
--nosignature::在讀取數據包時,不檢查簽名信息(不做源認證);
--nodigest:在讀取數據包的時候,不檢查摘要信息(不檢查完整性);
--prefix:對於可重新定位的二進位包,指定新的程式安裝位置。
--noscripts:不執行rpm包自帶的四類腳本;
--nopre:不執行rpm包自帶的preinstall腳本; ##安裝過程開始之前運行腳本,%pre, --pre
--nopost:不執行rpm包自帶的postinstall腳本; ##安裝過程完成之後運行的腳本,$post, --nopost
--nopreun:不執行rpm包自帶的preuninstall腳本; ##卸載過程開始之前運行的腳本, $preun, --nopreun
--nopostun:不執行rpm包自帶的postuninstall腳本; ##卸載過程完成之後運行的腳本,$postun , $--postun
常用格式
rpm -ivh PACKAGE_FILE ... ##PACKAGE_FILE表示指定rpm包路徑;
EXAMPLES
[root@Centos7 ~]# rpm -ivh zsh-5.0.2-14.el7_2.2.x86_64.rpm
Preparing... ################################# [100%]
Updating / installing...
1:zsh-5.0.2-14.el7_2.2 ################################# [100%]
[root@Centos7 ~]# rpm -qa | grep zsh
zsh-5.0.2-14.el7_2.2.x86_64
6.3 升級
SYNOPSIS
rpm {-U|--upgrade} [install-options] PACKAGE_FILE ...
rpm {-F|--freshen} [install-options] PACKAGE_FILE ...
OPTIONS
install-options
[--allfiles] [--badreloc] [--excludepath OLDPATH]
[--excludedocs] [--force] [-h,--hash]
[--ignoresize] [--ignorearch] [--ignoreos]
[--includedocs] [--justdb] [--nocollections]
[--nodeps] [--nodigest] [--nosignature] [--noplugins]
[--noorder] [--noscripts] [--notriggers]
[--oldpackage] [--percent] [--prefix NEWPATH]
[--relocate OLDPATH=NEWPATH]
[--replacefiles] [--replacepkgs]
[--test]
-U:升級或安裝比較新的軟體包(發現舊版本則升級,沒發現則直接安裝),安裝之後軟體包的所有其他版本將被移除;
-F:升級軟體包(只完成升級舊版本),如果之前沒有安裝則軟體也不會被安裝;
[install-options]
--oldpackage:升級以替代舊的包;
--force:強制升級;具有--replacepkgs、--replacefiles、--oldpackage的功能;
Note:
1. 不要對內核做升級操作;內核4.0之前的版本,要想使用新內核需要重啟才可以。但是重啟之後內核與系統可能發生不相容等問題。而且Linux支持多內核版本並存,因此,直接安裝新版本內核即可;
2. 如果某原程式包的配置文件安裝後曾被修改過,升級時,新版本的程式提供的同一個配置文件不會覆蓋原有版本的配置文件,而是把新版本的配置文件重命名(FILENAME.rpmnew)後保存;
EXAMPLES
[root@Centos7 ~]# rpm -Fvh zsh-5.0.2-28.el7.x86_64.rpm
Preparing... ################################# [100%]
Updating / installing...
1:zsh-5.0.2-28.el7 ################################# [ 50%]
Cleaning up / removing...
2:zsh-5.0.2-14.el7_2.2 ################################# [100%]
[root@Centos7 ~]# rpm -qa | grep zsh
zsh-5.0.2-28.el7.x86_64
6.4 卸載
SYNOPSIS
rpm {-e|--erase} [--allmatches] [--nodeps] [--noscripts] [--test] PACKAGE_NAME ...
OPTIONS
--allmatches:卸載所有匹配指定名稱的程式包的各版本;
--nodeps:忽略依賴關係;
--test:測試卸載,dry run模式;
註意:卸載和查詢時都無需程式文件路徑,只需給出rpm程式包名即可;
安裝和升級rpm程式包名需要rpm程式包文件完整路徑;
EXAMPLES
[root@Centos7 ~]# rpm -evh zsh
Preparing... ################################# [100%]
Cleaning up / removing...
1:zsh-5.0.2-28.el7 ################################# [100%]
[root@Centos7 ~]# rpm -qa | grep zsh
6.5 校驗
驗證(Verify)的功能主要在於提供系統管理員一個有用的管理機制!作用的方式是:使用/var/lib/rpm底下的資料庫內容來比對目前Linux系統的環境下的所有軟體文件。也就是說,當你有文件不小心遺失,或者是因為你誤刪了某個軟體的文件,或者是不小心不知道修改到某一個軟體的文件內容,就用這個簡單的方法來驗證一下原本的文件系統!
SYNOPSYS
rpm {-V|--verify} [select-options] [verify-options]
OPTIONS
verify-options
[--nodeps] [--nofiles] [--noscripts]
[--nodigest] [--nosignature]
[--nolinkto] [--nofiledigest] [--nosize] [--nouser]
[--nogroup] [--nomtime] [--nomode] [--nordev]
[--nocaps]
-V :後面加的是軟體名稱,若該軟體所含的文件被更動過,才會列出來;
-Va :列出目前系統上面所有可能被更動過的文件;
-Vp :後面加的是文件名稱,列出該軟體內可能被更動過的文件;
-Vf :列出某個文件是否被更動過;
[verify-options]
--nodeps 不驗證數據包的依賴關係;
--nodigest 在讀取時,不驗證數據包的完整性;
--nofiles 不驗證數據包文件的任何屬性是否發生改變;
--noscripts 不執行校驗腳本;
--nosignature 在讀取時,不驗證數據包的簽名;
EXAMPLES
S:文件大小發生改變
M:文件ugo訪問許可權發生改變
5:文件的摘要發生變化
D:設備的主/次設備號發生改變
L:路徑的發生改變
U:屬主發生改變
G:屬組發生改變
T:mtime發生改變
P:功能的發生改變
c :配置文件
d :幫助文件
g :ghost文件,通常是該文件不被某個軟體所包含,較少發生!(ghost file)
l :授權文件
r :read me文件
logrotate這個軟體生成了12個文件
[root@Centos7 ~]# rpm -ql logrotate
/etc/cron.daily/logrotate
/etc/logrotate.conf
/etc/logrotate.d
/etc/rwtab.d/logrotate
/usr/sbin/logrotate
/usr/share/doc/logrotate-3.8.6
/usr/share/doc/logrotate-3.8.6/CHANGES
/usr/share/doc/logrotate-3.8.6/COPYING
/usr/share/man/man5/logrotate.conf.5.gz
/usr/share/man/man8/logrotate.8.gz
/var/lib/logrotate
/var/lib/logrotate/logrotate.status
對這些文件進行校驗
[root@Centos7 ~]# rpm -V logrotate
S.5....T. c /etc/logrotate.conf ##文件大小發生變化、文件的摘要發生變化、文件的mtime發生變化、這個c表示這個文件是一個配置文件
6.6 來源合法性驗證和完整性校驗
談完了軟體的校驗後,不知道你有沒有發現一個問題,那就是,驗證只能驗證軟體內的資訊與/var/lib/rpm/ 裡面的資料庫信息而已,如果該軟體文件所提供的信息本身就有問題,那使用驗證的手段也無法確定該軟體的正確性。
來源合法性驗證:
數字簽名:通過md5/sha等單向加密技術,計算出一個數據的特征碼(定長的),然後使用私鑰加密這個特征碼,並將加密後的值附加到放到RPM包里,最後發佈。最後拿到這個RPM包的人,只要有對應的公鑰就能解密這段特征碼。因為能解密,從而驗證了來源合法性,但是因為數據包有沒有加密,如何確定數據包沒有被更改呢?
確保數據的完整性:
拿到RPM包的人使用和發佈者同樣的加密演算法對數據進行單向加密從而生成定長特征碼,如果解密得來的特征碼和自己計算數據包得來的特征碼一致,就代碼數據沒有被篡改過。但是前面所說的方法,都是建立在公鑰沒有被篡改過的前提下,那但是如何確保公鑰沒有被篡改過呢?
確保公鑰的完整性:
待續
導入密鑰信息
SYNOPSIS
rpmkeys --import PUBKEY ...
rpmkeys {-K|--checksig} PACKAGE_FILE ...
OPTIONS
The --checksig option checks all the digests and signatures contained in PACKAGE_FILE to ensure the integrity and origin of the package.
--checksing
EXAMPLES
安裝此組織簽名的程式時,會自動執行驗證;
手動驗證:rpm -K PACKAGE_FILE
特定的公鑰信息,可以通過以下方式顯示:
rpm -qi gpg-pubkey-db42a60e
擦除都被導入的公鑰,可以通過以下方式:
rpm -e gpg-pubkey-db42a60e
[root@Centos7 ~]# rpm -K zsh-5.0.2-28.el7.x86_64.rpm
zsh-5.0.2-28.el7.x86_64.rpm: rsa sha1 (md5) pgp md5 OK
[root@Centos7 ~]# rpm --checksig zsh-5.0.2-28.el7.x86_64.rpm
zsh-5.0.2-28.el7.x86_64.rpm: rsa sha1 (md5) pgp md5 OK
導入信任的包製作者的密鑰:
iso文件的根目錄就有例如:RPM-GPG-KEY-CentOS-7
對於CentOS發行版來說:rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
6.7 資料庫重建
rpm包資料庫位置:/var/lib/rpm
查詢操作(包括安裝、升級、卸載、查詢、檢驗):都是通過此處的資料庫進行的;
獲取重建幫助
CentOS6:man rpm
CentOS7:man rpmdb
SYNOPSIS
rpm {--initdb|--rebuilddb} [--dbpath DIRECTORY] [--root DIRECTORY]
OPTIONS
--dbpath:指定資料庫的路徑(預設為:/var/lib/rpm)
--initdb:初始化資料庫,當前無任何資料庫則創建一個,當前有資料庫則不執行任何操作;
--rebuilddb:重新構建,通過讀取當前系統上所有已經安裝過的程式包進行重新創建;無論當前是否存在資料庫,都直接重新創建資料庫;
EXAMPLES
rpm --rebuilddb --dbpath=/var/lib/rpm/