本章咱們來介紹Linux程序包的概念及安裝校驗卸載等管理操做。php
咱們不止一遍講述過操做系統的概念,首先是硬件,計算機它的計算能力都是在硬件設計邏輯上實現的,而這個設計硬件設計邏輯不一樣廠商所生產的硬件芯片及接口的方式都不同。那麼在向上一層就是將硬件規格給封裝起來的操做系統層,它將硬件的差別化和複雜化而由醜陋的接口隱藏起來,向上提供了一個簡潔而又統一的接口,咱們稱之爲系統調用(system call),但系統調用仍然很底層,爲了加速開發和易於維護,在系統調用的半層接口上又封裝了一個更復雜的接口,咱們稱之爲庫調用(lib call),由於對於程序開發者來說,既能夠面向半層來寫程序,又能夠面向操做系統層上的系統調用接口來寫程序,最後在向上就是各類各樣的應用程序了,而對於主要的對於生產力來講就是在操做系統上跑的應用程序,在衆多應用程序當中,還有讓用戶與主機交互的咱們稱之爲shell程序,因此,各類各樣的任務操做都是由應用程序來完成的。前端
因此在運維過程當中,除了系統管理及庫調用以外,最主要就是在操做系統上安裝及配置程序包,而後讓該程序運行起來,並提供服務,或完成某種具體的相應操做的過程,安裝及卸載程序包,是運維最基本也是最根本的任務,由於咱們須要實現安裝及管理程序包等操做。可是,任何程序的運行,在程序包上會提供至少兩種的格式的安裝包,一種爲源碼包,另外一種爲二進制包,那麼咱們就得須要回顧一下API
和ABI
。java
API層次兼容未必就ABI層次兼容,由於有些操做系統的執行格式並不是是相同的,對於類Unix程序來講,它們的執行程序爲ELF
,對於Windows來講,它們的執行格式爲.exe
,或msi
,所以它們在ABI層次上並不兼容,即便用高級語言編寫的程序,在源碼層是兼容的,但對二進制層來講相互並不必定兼容。因此說帶來的結果是若是在將源碼包在Linux上編譯好了,在Windows上運行是很難實現的,反過來也亦是如此。
不過,雖然很難,咱們能夠藉助於虛擬化,使得兩者的差別性將其磨平,好比如今各類應用程序,幾乎都是針對庫調用來開發的,在系統調用上開發也是沒有問題的,如今有不少Windows程序也模擬Linux庫的程序,相反也有Linux模擬Windows庫的程序,好比說WinE,在Windows咱們能夠安裝Cywin來進行模擬。node
概述: API:Application Program Interface ABI:Application Binary Interface Unix -like ELF Windows exe, msi 庫級別的虛擬化: Linux:WinE Windows:Cywin
不過,這些都是一些虛擬化的藉助工具而已,因爲ABI和庫調用是不兼容的或不相同的在二進制層次上,它們並無辦法實現互相調用。python
那麼各類編程語言當中,對於高級語言來講,大致分爲兩類,一種是系統級開發,還有一種是應用級開發,有些程序對於系統要求比較嚴苛並且是服務級別的程序的話,可能會使用系統級開發來編寫該程序,如今的程序可能柔和多種編程語言的風格,對於系統要求較高的,都會使用系統級開發去編寫該程序,而使用應用級開發有多是對用戶來講去寫一些輔助程序,因此咱們來總結一下。nginx
系統級開發: C/C++:httpd, vsftpd, nginx go 應用級開發: Java/Python/perl/ruby/php java: hadoop, hbase Python: OpenStack perl: perl ruby:(ruby) php:(php)
但不管是哪種應用程序,像C/C它們依賴於庫,這種庫是由系統根據某一種標準來提供的,而這裏的庫調用指的就是C/C的庫,在系統中/lib或/lib64等目錄,指的就是裏面的庫程序,而它們一般是共享庫,而應用級別,例如Java,要想運行某個Java程序,須要依賴於JVM
,也就是Java虛擬機,同時,Python也是同樣,要想運行須要依賴於PVM
,也就是Python虛擬機,而這種解釋器或虛擬機,是由C/C++開發的,所以對於應用級開發來講,運行性能會差一些,可是代碼量較小,庫接口豐富,因此寫代碼的週期較短一些,不過須要確保運行的環境存在,則能夠運行該程序。c++
不過,因爲拿到的程序有多是兩種格式,這裏指C/C++來講,一種爲源代碼,另外一種爲二進制,對於源代碼來講,就是由文本格式編寫的程序代碼,萬一只是提供了源代碼,咱們是須要進行手工編譯的,而要想進行編譯,須要依賴編譯開發環境,而提供開發環境是一件很費力的一件事情,而對於二進制來講是由文本格式的程序代碼通過編譯器成爲該平臺運行後的二進制格式,不過對於二進制格式文件來講,有四類文件組成,咱們來總結一下:redis
C/C++程序格式: 源代碼:文本格式的程序代碼; 編譯開發環境:編譯器、頭文件、開發庫; 二進制格式:文本格式的程序代碼 --> 編譯器 --> 二進制格式(二進制格式、庫文件、配置文件、幫助文件);
在二進制格式中,配置文件是由文本保存的,這也是Linux重要的哲學思想之一,因此的配置信息保存在文本文件裏,這樣作的好處是可使用不一樣的文本編輯器能夠打開該配置文件。shell
而對於java/Python等這樣的應用級開發語言來講,它們的格式也是同樣的,也無非就是源代碼或二進制,對於源代碼來講也是須要編譯的,但不一樣的是,它們的編譯與系統級開發的語言編譯有所不一樣,由於應用級開發語言的編譯並非指的是在CPU上運行的二進制格式,而是可以編譯成其在虛擬機上所運行的二進制格式,意味着虛擬機可以轉換或翻譯成CPU所理解的格式,中間多了一層,因此說性能差也就是這個緣由,而不管是C仍是java,它們生成的目標程序文件都不止一個,因此咱們在編譯程序時,有可能會出現錯綜複雜的依賴關係,這樣也致使有可能先編譯第一個,不過依賴於第二個,那就先把被依賴的程序先編譯,或許第二個也依賴於第三個,除非能讀懂源代碼,所以各類各樣的源代碼都會使用一個項目構建工具來實現。數據庫
對於java和python來講,它們也有本身的開發環境,只不過它們的開發環境就是所對應的應用程序的虛擬機,和虛擬機所提供的編譯器。也須要開發庫,只不過沒有頭文件而已。
java/Python程序格式: 源代碼:編譯成可以在其虛擬機(jvm/pvm)運行的格式; 開發環境:編譯器、開發庫 二進制 項目構建工具: c/c++:make java:maven
因此說爲了下降終端用戶的使用難度,咱們就要使用程序包來協助終端用戶的管理工做。
俗話說:送佛送到西,那麼在這裏的意思就是這個源代碼程序,爲了儘量提升終端用戶的體驗,將源代碼編譯成可在所須要的目標系統上能運行的二進制格式,不過編譯完成以後,其實除了二進制文件及庫文件還有幫助文件及配置文件,編譯起來也是很是困難,因此在編譯好以後,把這四類文件按照特定的方式組織起來,組織成一個或有限幾個"包"文件,要成爲包文件的話,它必需要實現幾個基本操做,好比:安裝、卸載、查詢升級等操做,甚至對於Linux來講還能實現校驗的操做。
而將源代碼轉換成目標二進制文件(包含這四類文件),而要想組織成一個或有限幾個包文件的話,這就須要包管理器來實現。
對於Linux來講,咱們得須要知道它背後發生了什麼,由於它是個自由軟件程序,自由的代價是責任,本身須要去實現各類各樣的功能,然後還要對其背後的運做過程有所瞭解,纔可以真正實現自由的目的,因此說這個程序包怎麼組織實現及如何使用,咱們都須要知道其背後如何運做。
Linux發行版共有三大主流分支,分別是Debian
、RedHat
和S.u.S.E
,它們使用的程序包管理器,並不必定徹底相同,由於自由,各自爲站,那麼對於三大陣營的程序包管理器咱們總結一下。
程序包管理器: 源代碼 --> 目標二進制格式(二進制程序、庫文件、配置文件、幫助文件) --> 組織成爲一個或有限幾個"包文件"; 安裝、升級、卸載、查詢、校驗; 程序包管理器: debian:dpt, dpkg, ".deb" redhat:redhat package manager, rpm, ".rpm"; rpm is package manager S.u.S.E:rpm, ".rpm" Gentoo:ports ArchLinux:
那麼接下來咱們說一下程序包的組成格式,Linux的重要組成思想叫作一個程序只作一件事,而且作好,組個小程序可以完成複雜任務。因此說帶來的結果就是,因此說程序包都是簡單而又單一的,而單個程序一般很是簡單,而帶來的結果就是一個程序運行的話,可能要依賴於其它程序,不過咱們先說一下程序包的組成格式,咱們先說一下源代碼的組成包,源碼包的一般的命名格式爲:name-VERION.tar.gz
,而rpm包命名格式爲:name-VERSION-release.arch.rpm
,而對於VERSION
來講,包含什麼,以及包名的詳細信息,咱們總結以下:
源代碼:name-VERION.tar.gz VERSION: major.minor.release 主 次 發行 主:表明重大的版本分支; 次:在這個分支版本進行改變; 發行:修復某個bug; rpm包命名格式: name-VERSION-release.arch.rpm VERSION: major.minor.release release.arch: rpm包的發行號; release.os:2.el7.i386.rpm archetecture: i386, X64(amd64), ppc, noarch redis-3.0.2.tar.gz --> redis-3.0.2-1.centos7.x64.rpm
每一次版本演進會有chagelog,主要發生了那些改變,詳細都會有相關的說明,而這種文檔就叫作chagelog。除了i386還有i686,區別就是對於CPU的新舊支持,i386可以支持較老的32位CPU,i686支持較新的32位CPU,對咱們來說並無太大區別。
對於rpm包來講,有拆包的習慣,其緣由就是有不少種程序功能可能並不須要,將一個包的多種功能給它拆分紅多個組成部分,因此使得用戶能夠按需安裝,拆完以後就分爲了主包和支包,主包就是與該程序命名相同,而支包就是命名加上該功能(function)便可。
拆包:主包和支包 主包:name-VERSION-release.arch.rpm 支包:name-funcation-VERSION-release.arch.rpm function: devel, utils, libs, ...
拆成多個包以後,頗有可能會存在依賴關係,在Linux中,每一個程序都作到短小精悍,因此每一個程序包的體積都是很小的,可是這樣一來,每一個程序包都很簡單,因而必需要依賴於其它依賴包的功能所可以爲本身運行。因此包與包之間會存在複雜的關係,好比說咱們去安裝X包,X又依賴於Y和Z,而安裝Y時又依賴A、B、C,而C又依賴於Y,那麼這是一種循環依賴關係,若是要強制安裝的話,其功能沒法徹底發揮出來。若是有自動解決的前端工具,這種工具藉助於包管理器自動解決包和包之間的依賴關係,從而安裝那個安裝包依賴性都會自動給予解決。
依賴關係: X, Y, Z X --> Y,Z Y --> A, B, C C --> Y 前端工具:自動解決依賴關係; yum:rpm包管理器的前端工具; apt-get(apt-cache):deb包管理器的前端工具; zypper:suse的rpm管理器前端工具; dnf:Fedora22+系統上rpm包管理器的前端工具;
前端管理工具能解決後端管理工具的諸多不便之處,這樣使得管理操做更爲簡潔。不過咱們須要先學習後端包管理工具的用法,而後再去學前端管理工具所帶來的各類功能,最後咱們可使用源代碼包來進行編譯安裝。
咱們說一下程序包管理器的自己,其功能和組成部分爲:
程序包管理器: 功能:將編譯好的應用程序的各組成文件打包成一個或幾個程序包文件,從而更方便地實現程序包的安裝、升級、卸載和查詢等管理操做;
所以,一個程序包的組成格式,大致上有如下幾種:
一、程序包的組成清單(每一個程序包都單獨實現); 文件清單; 安裝或卸載時運行的腳本 二、數據庫(公共) 程序包的名稱和版本; 依賴關係; 功能說明; 安裝生成的各文件的文件路徑及驗證碼信息; 等等等 /var/lib/rpm
要想安裝或管理程序包的話,得先知道從某些位置去獲取安裝包,對於開源的程序包,收費的數量不多,因此不存在什麼盜版問題,可是可能存在篡改問題,因此要在正規途徑獲取,那麼獲取程序包的方式總結以下:
獲取程序包的途徑: (1) 系統發行版的光盤或官方的文件服務器(或鏡像站點); http://mirrors.aliyun.com http://mirrors.163.com (2) 項目的官方站點 (3) 第三方組織 (a) EPEL (B) 搜索引擎 http://pkgs.org http://rpmfind.org http://rpm.phone.net (4) 本身動手,豐衣足食; 建議:檢查其合法性 來源合法性 程序包的完整性
其實對於安裝包的管理來講無非就是:
安裝、升級、卸載、查詢和校驗、數據庫維護
以上前五種都使用rpm命令來實現管理,該命令格式以下:
rpm命令:rpm [OPTIONS] [PACKAGE_FILE]
若是要想查詢該安裝包的話,只需在後面跟上該安裝包的名稱而已,而安裝時必需要指明PACKAGE_FILE才能夠,該命令的選項以下:
安裝:-i, --install 升級:-U, --update, -F, --frshen 卸載:-e, --erase 查詢:-q, --query 校驗:-V, --verify 數據庫維護:--builddb, initdb
每一種功能都有不少專用的子選項,有許多複雜的使用機制,安裝的子命令及選項爲:
安裝: rpm {-i|--install} [install-options] PACKAGE_FILE rpm -ivh PACKAGE_FILE GENERAL OPTIONS -v: verbose, 詳細信息; -vv: 更詳細的輸出; [install-options]: -h: hash marks輸出進度條;每一個#表示2%的進度; --test:測試安裝,檢查並報告依賴關係及衝突信息等; --nodeps: 忽略依賴關係;不建議; --replacepkgs: 從新安裝,但不能重置配置文件;
每個程序包在安裝時會自帶運行一些腳本,共分爲四類,來作一些準備操做,因此咱們須要注意的是:
注意: rpm能夠自帶腳本; 四類:--noscripts preinstall:安裝過程當中開始以前運行的腳本,%pre, --nopre postinstall:安裝過程完成以後運行的腳本,%post --nopost preuninstall:卸載過程真正開始執行以前運行的腳本,%perun, --nopreun postuninstall:卸載過程完成以後運行的腳本,%postun, --nopostun --nosingnature:不檢查簽名信息,及不檢查來源合法性; --nodigest:不檢查包完整性信息;
以上就是安裝程序包的內容,接下來咱們開始講述如何升級安裝包,一旦某個程序包發現了嚴重了bug
,或者是某個功能有個重大版本演進的時候,咱們將會把該程序包升級爲較新的版本中。而升級所用到的rpm包的操做與安裝是相似的,只不過將安裝換成了升級而已。那麼升級的子命令爲:
升級: rpm {-U|--upgrade} [install-options] PACKAGE_FILE ... rpm {-F|--freshen} [install-options] PACKAGE_FILE ... -U:升級或安裝; -F:升級; rpm -Uvh PACKAGE_FILE ... rpm -Fvh PACKAGE_FILE ... --oldpackage:降級; --force:強制升級;
對於升級安裝包來講,咱們須要注意的是:
注意: (1) 不要對內核升級:Linux支持多內核版本並存,所以,直接安裝新版本內核; (2) 若是原程序包的配置文件安裝後曾被修改過,升級時,新版本的程序提供一個配置文件不會覆蓋原有的版本的配置文件,而是把新版本的配置文件重命名爲(FILENAME.rpmnew)後提供(保留);
接下來講卸載安裝包的操做,卸載就是將該程序從系統中移除,那麼卸載的子命令爲:
卸載: rpm {-e|--erase} [--allmatches] [--nodeps] [--noscripts] [--test] PACKAGE_FILE ... --allmatches:卸載全部的匹配製定名稱的程序包的各個版本‘ --nodeps:忽略依賴關係; --test:測試卸載,dry run模式;
查詢安裝包對咱們來說是一件很是重要的功能及能力,未來常常能用到,也是很是重要的一個操做手段,並且它的選項也很是之多,那麼查詢的子命令爲:
查詢: rpm {-q|--query} [select-options] [query-options] [select-options] PACKAGE_NAME:查詢指定程序包是否已經安裝,及其版本; -a, --all:查詢全部已經安裝過的包; -f FILE:查詢指定的文件由那個程序包安裝生成; -p, --package PACKAGE_FILE:用於實現對未安裝的程序包執行查詢操做; --whatprovides CAPABILITY:查詢指定的CAPABILITY由那個程序包提供; --whatrequires CAPABILITY:查詢指定的CAPABILITY被那個包所依賴; [query-options] --chagelog:查詢rpm包的chagelog; -l, --list:程序安裝生成的全部文件列表; -i, --info:程序包相關的信息,版本號、大小、所屬的包組,等; -c, --configfiles:查詢指定的程序包提供的配置文件; -d, --docfiles:查詢指定的程序包提供的文檔; --provides:列出指定的程序包提供的全部的CAPABILITY; -R, --requires:查詢指定的程序包的依賴關係; --scripts:查看程序包自帶的腳本片斷; 用法: -qi PACKAGE, -qf FILE, -qc PACKAGE, -ql PACKAGE, -qd PACKAGE, -qpl PACKAGE_FILE, -qpi PACKAGE_FILE, -qpc PACKAGE_FILE
校驗是用來查看該程序包是否該篡改,以及檢查它的來源合法性,那麼校驗該子命令的用法爲:
校驗: rpm {-V|--verify} [select-options] [verify-options] S file Size differs (文件大小發生改變) M Mode differs (include permissions and file type) (文件權限發生改變) 5 digest (formerly MD5 sum) differs (MD5發生改變,內容完整性改變) D Device major/minor number mismatch (主/次設備號不匹配) L readlink(2) path mismatch (readlink路徑不匹配) U User ownership differs (屬主發生改變) G Group ownership differs (屬組發生改變) T mTime differs (時間戳發生改變) P caPabilities differ (capabilites發生改變)
對於安裝包的合法性及完整性,咱們是須要驗證的,那麼安裝包的來源及合法性驗證以下:
包來源合法性驗證和完整性驗證: 來源合法驗證; 完整性驗證;
對於來源合法性來講,指的就是咱們去檢查驗證由官方簽發的數字簽名,由非對稱加密來實現,生成密鑰對兒,稱爲公鑰和私鑰,公鑰加密後的數據由該私鑰解密,反之亦然,使用私鑰加密的由該公鑰去解密。每個組織後每一個人製做包的時候,就會製做一對兒密鑰,而後用本身的私鑰進行簽名,而公鑰是能夠公開的,因此只要能解密出來,就能夠認爲該程序包是原做者的。要想獲取程序包的公鑰的話,咱們能夠經過安裝盤來得到,名稱爲RPM-GPG-KEY-CentOS-7
,或者在系統上/etc/pki/rpm-gpg/
目錄下也有該文件,經過它來獲取公鑰驗證程序包的合法與完整性。
獲取並導入信任的包製做者的密鑰: 對於CentOS發行版來講:rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 RPM-GPG-KEY-CentOS-7 驗證: (1) 安裝此組織簽名的程序時,會自動執行驗證; (2) 手動驗證:rpm -k PACKAGE_FILE;
全部的數字簽名都是用本身的私鑰去加密對應數據的特徵碼,這樣能夠實現兩重做用,第一就是來源合法性,第二就是數據完整性能夠作到驗證。但這兩種加密方式並不涉及保密性的概念及功能。
數據庫重建這個工做未必可以重建起來,建議不要測試在生產環境中,rpm包管理器經過某個數據庫來對包進行查詢操做的,該路徑在/var/lib/rpm
目錄下,因此安裝的所生成的那些文件及目錄信息由數據庫記錄及提供,因此查詢操做就是由該數據庫來實現的。萬一數據庫損壞,咱們能夠進行重建,通常來講有兩種來進行數據庫的重建操做。
數據庫重建: rpm管理器數據庫路徑:/var/lib/rpm 查詢操做:經過此處的數據庫進行; 獲取幫助: CentOS 6: man rpm CentOS 7: man rpmdb rpm {--initdb|--rebuilddb} [--dbpath DIRECTORY] [--root DIRECTORY] --initdb:初始化數據庫,當前無任何數據庫可實例化建立一個新的數據庫;已存在時不執行任何操做’ --rebuilddb:從新構建,經過讀取當前系統上全部已經安裝過的程序包進行從新建立;