您好,登錄后才能下訂單哦!
第一部分:程序編譯過程
一、軟件運(yùn)行環(huán)境介紹
應(yīng)用視角ABI:Application Binary Interface 應(yīng)用二進(jìn)制接口,程序應(yīng)用者面對(duì)運(yùn)行程序的接口,應(yīng)用程序與調(diào)用庫之間的接口。
Linux:ELF(Executable and Linkable Format)
Windows:PE(Portable Executable)
二、軟件編譯過程
??我們獲取應(yīng)用程序的源碼包后不能直接運(yùn)行在操作系統(tǒng)平臺(tái),需要通過編譯成不同操作系統(tǒng)支持ABI的才有運(yùn)行在不同的操作系統(tǒng)平臺(tái)上
程序源代碼 --> 預(yù)處理 --> 編譯 --> 匯編 --> 鏈接
1.預(yù)處理: 根據(jù)程序源代碼中的預(yù)處理指令格式化源代碼并輸出為.i結(jié)尾的文件為編譯做準(zhǔn)備
2.編譯: 對(duì)預(yù)處理文件進(jìn)行編譯,生成了匯編文件,基于.i文件中的預(yù)編譯指令生成.s文件,里面保存的是匯編代碼
3.匯編: 對(duì)匯編文件進(jìn)行編譯,生成了目標(biāo)文件,基于編譯過程生成的.s文件里的匯編代碼轉(zhuǎn)換成二進(jìn)制機(jī)器碼,最后輸出為.o文件
4.鏈接: 對(duì)目標(biāo)文件進(jìn)行鏈接,生成可執(zhí)行文件,將匯編生成的二進(jìn)制文件及程序調(diào)用的庫文件鏈接打包生成執(zhí)行文件,鏈接分為兩種因此編譯分為兩種:一種是靜態(tài)編譯,一種是動(dòng)態(tài)編譯
? 靜態(tài)編譯:
將程序調(diào)用的第三方庫文件一起找包生成可執(zhí)行文件,特點(diǎn)是安裝時(shí)將依賴的第三方庫文件一起釋放安裝,解決目標(biāo)操作系統(tǒng)平臺(tái)因沒有依賴的庫文件而運(yùn)行失敗的問題。但是靜態(tài)鏈接生成的可執(zhí)行程序體積較大,如果程序更新則需要重新再次編譯。靜態(tài)庫后綴為.a文件
? 動(dòng)態(tài)編譯:
只是對(duì)程序調(diào)用的第三方庫文件做個(gè)鏈接,并不真正將依賴的庫文件打包在可執(zhí)行文件內(nèi),而是做一個(gè)動(dòng)態(tài)鏈接。在目標(biāo)系統(tǒng)程序運(yùn)行時(shí)調(diào)用目標(biāo)操作系統(tǒng)中的庫就可以,但如果沒有依賴的庫的則會(huì)運(yùn)行失敗。動(dòng)態(tài)庫為.so文件
5.GCC編譯過程
? 預(yù)處理:生成預(yù)編譯文件(.文件):gcc –E hello.c –o hello.i
(對(duì)hello.c文件進(jìn)行預(yù)處理,生成了hello.i 文件)
? 編譯:生成匯編代碼(.s文件):gcc –S hello.i –o hello.s
(對(duì)預(yù)處理文件進(jìn)行編譯,生成了匯編文件 )
? 匯編:生成目標(biāo)文件(.o文件):gcc –c hello.s –o hello.o
(對(duì)匯編文件進(jìn)行編譯,生成了目標(biāo)文件)
? 鏈接:生成可執(zhí)行文件:gcc hello.o –o hello
(對(duì)目標(biāo)文件進(jìn)行鏈接,生成可執(zhí)行文件)
三、Linux系統(tǒng)中應(yīng)用程序介紹
??系統(tǒng)內(nèi)安裝的程序分兩部分存儲(chǔ)信息,一部分為程序的元數(shù)據(jù)信息,另一部分有應(yīng)用程序數(shù)據(jù)。
1.程序的元數(shù)據(jù):
??系統(tǒng)內(nèi)安裝的rpm程序包信息(名稱,版本,依賴性,描述等 )都被注冊(cè)在rpm數(shù)據(jù)庫內(nèi),每次安裝rpm包都會(huì)查詢數(shù)據(jù)庫程序是否已經(jīng)存在,如果存在則rpm包管理器則會(huì)反饋不同的信息。該數(shù)據(jù)庫位于/var/lib/rpm
? 程序包名稱及版本
? 依賴關(guān)系
? 功能說明
? 包安裝后生成的各文件路徑及校驗(yàn)碼信息
rpm 系統(tǒng)出了問題,不能安裝和查詢,可能會(huì)是數(shù)據(jù)庫出現(xiàn)問題,可以使用下面命令重建
rpm --initdb:如果事先沒有數(shù)據(jù)庫,則會(huì)新建一個(gè),如果已經(jīng)存在數(shù)據(jù)庫則不進(jìn)行任何操作
rpm –rebuilddb:重新構(gòu)建數(shù)據(jù)庫,會(huì)覆蓋原有數(shù)據(jù)庫
2.應(yīng)用程序數(shù)據(jù):
??應(yīng)用程序數(shù)據(jù)才是我們真正使用的能夠被向操作系統(tǒng)提請(qǐng)為進(jìn)程的程序文件
3.庫文件:
??Linux下很多應(yīng)用程序都是動(dòng)態(tài)編譯生成的,因此會(huì)很多程序都依賴系統(tǒng)提供的基本庫文件,而且很多應(yīng)用程序間也存在著依賴關(guān)系,為系統(tǒng)提供了高效規(guī)范的處理這些依賴關(guān)系將所有可用庫文件名及文件路徑 映射關(guān)系以模塊化的配置文件形式存在指定位置,并向用戶提供了應(yīng)用程序與庫文件之間依賴關(guān)系查詢的命令接口,具體如下:
? 配置文件位置:/etc/ld.so.conf, /etc/ld.so.conf.d/*.conf
? 緩存文件位置:/etc/ld.so.cache
? ldd命令:查看二進(jìn)制程序所依賴的庫文件 例:ldd /usr/bin/cat
? 管理及查看本機(jī)裝載的庫文件
? ldconfig加載配置文件中指定的庫文
? ldconfig -p顯示本機(jī)已經(jīng)緩存的所有可用庫文件名及文件路徑映射關(guān)系
4.rpm包介紹
1.rpm包名稱
包名稱-[功能備注]-主版本號(hào).次版本號(hào).修正號(hào)-編譯次數(shù)-發(fā)行商定制的發(fā)行版本號(hào)-硬件架構(gòu)平臺(tái).rpm
? 功能備注:tools工具包、devel開發(fā)包、libs庫、utils功能包、
? 主版本號(hào):功能模塊或架構(gòu)上有大的變更
? 次版本號(hào):功能模塊加強(qiáng)
? 修正號(hào):bug修復(fù)
2. rpm包結(jié)構(gòu):
? RPM包內(nèi)的程序文件
? RPM的元數(shù)據(jù),如名稱,版本,依賴性,描述等
? 安裝或卸載時(shí)運(yùn)行的腳本 (用于定制配置文件,如創(chuàng)建用戶等)
第二部分:程序包管理
??rpm程序包管理工具將編譯好的應(yīng)用程序的各組成文件打包一個(gè)或幾個(gè)程序包文件,從而 方便快捷地實(shí)現(xiàn)程序包的安裝、卸載、查詢、升級(jí)和校驗(yàn)等管理操作
一.rpm選項(xiàng)介紹
??rpm程序包管理工具的選項(xiàng)比較多,這里還是總結(jié)一下rpm的man手冊(cè)內(nèi)各選項(xiàng)之間的搭配關(guān)系。我們可以把rpm的選項(xiàng)分為三個(gè)級(jí)別來理解記憶,一級(jí)為包管理類選項(xiàng)命令行內(nèi)必選選項(xiàng),二級(jí)為可選的功能性微調(diào)選項(xiàng),三級(jí)輔助通用選項(xiàng):-v顯示詳細(xì)信息、-h顯示處理進(jìn)度
1.一級(jí)包管理類必選選項(xiàng):
-i安裝、-e卸載、-U -F升級(jí)、-V校驗(yàn)、-q查詢
查詢、校驗(yàn)操作都可以搭配[select-options]
包的安裝、升級(jí)操作都可以搭配[install-options]
包卸載操作搭配的選項(xiàng)則比較混亂我們只需記住-e
2.二級(jí)功能性微調(diào)可選選項(xiàng):
安裝選項(xiàng)、查詢選項(xiàng)、校驗(yàn)選項(xiàng)、選擇選項(xiàng),詳細(xì)信息見文章最后的微調(diào)選項(xiàng)附錄部分
3.一、二級(jí)選項(xiàng)搭配關(guān)系:
1.包查詢操作:搭配選擇項(xiàng)或查詢選項(xiàng)
rpm {-q|--query} [select-options] [query-options]
2.包校驗(yàn)操作:搭配選擇項(xiàng)或校驗(yàn)選項(xiàng)
rpm {-V|--verify} [select-options] [verify-options]
3.包安裝操作:搭配安裝選項(xiàng)
rpm {-i|--install} [install-options] PACKAGE_FILE …
4.包重新安裝:搭配安裝選項(xiàng)
rpm {--reinstall} [install-options] PACKAGE_FILE ...
5.包升級(jí)操作:搭配安裝選項(xiàng)
rpm {-U|--upgrade} [install-options] PACKAGE_FILE …
rpm {-F|--freshen} [install-options] PACKAGE_FILE ...
6.包卸載操作:
rpm {-e|--erase} [--allmatches] [--justdb] [--nodeps] [--noscripts][--notriggers] [--test] PACKAGE_NAME ...
4.通用選項(xiàng):卸載、安裝都適用
通用選項(xiàng)可以輔助安裝、卸載等一級(jí)選項(xiàng)更詳細(xì)的顯示rpm的處理過程
? -v verbose顯示詳細(xì)信息,可以多個(gè)v疊加,顯示不同級(jí)別的詳細(xì)信息
? -h 顯示包管理程序的處理進(jìn)度
二、包管理操作
1.程序包安裝
程序安裝過程:
? 執(zhí)行安裝前的腳本文件,如創(chuàng)建用戶、創(chuàng)建必要的目錄、權(quán)限設(shè)置
? 解包將各種文件復(fù)制到相應(yīng)的目錄。
? rpm包安裝完后會(huì)自動(dòng)注冊(cè)在RPM公共數(shù)據(jù)庫中/var/lib/rpm,便于后期卸載、查詢操作
語法:
rpm {-i|--install} [install-options] PACKAGE_FILE…
--test: 測(cè)試安裝,但不真正執(zhí)行安裝,即dry run模式
--nodeps:忽略依賴關(guān)系,強(qiáng)制定包
--force 強(qiáng)行安裝
--replacepkgs | replacefiles 替換包或文件 用于。替換原有包,覆蓋安裝。
--nosignature: 不檢查來源合法性
--nodigest:不檢查包完整性
--noscripts:不執(zhí)行程序包腳本
%pre: 安裝前腳本 --nopre
%post: 安裝后腳本 --nopost
%preun: 卸載前腳本 --nopreun
%postun: 卸載后腳本 --nopostun
常用選項(xiàng)組合
? 覆蓋原有包:修改因包文件被誤刪除導(dǎo)致重新安裝失敗
rpm -ivh tree-1.7.0-15.el8.x86_64.rpm --replacepkgs
? 覆蓋原有文件:
rpm -ivh tree-1.7.0-15.el8.x86_64.rpm --replacefiles
? 跳過包簽名校驗(yàn)
rpm -ivh tree-1.7.0-15.el8.x86_64.rpm --nosignature
實(shí)用小技巧
判斷一個(gè)軟件包是否存在,如果不存在則安裝相應(yīng)的軟件包
rpm -q tree > /dev/null ||rpm -ivh ../../BaseOS/Packages/tree-1.7.0-15.el8.x86_64.rpm
2.程序包卸載
語法:
rpm {-e|--erase} [--allmatches] [--justdb] [--nodeps] [--noscripts]
? --allmatches 卸載所有匹配的包,匹配指定的關(guān)鍵字的包全部卸載
? --justdb
? --nodeps 忽略依賴關(guān)系強(qiáng)行卸載
? --noscripts 執(zhí)行卸載過程中不執(zhí)行卸載腳本
小提示: 當(dāng)包卸載時(shí),對(duì)應(yīng)的配置文件不會(huì)刪除, 以FILENAME.rpmsave形式保留 如httpd的http.conf文件
3.程序包升級(jí)
語法:
upgrade:安裝有舊版程序包,則“升級(jí)” 如果不存在舊版程序包,則“安裝”
rpm {-U|--upgrade} [install-options] PACKAGE_FILE...
freshen:安裝有舊版程序包,則“升級(jí)”如果不存在舊版程序包,則不執(zhí)行升級(jí)操作
rpm {-F|--freshen} [install-options] PACKAGE_FILE...
4.程序包降級(jí)
降級(jí)一般用于業(yè)務(wù)測(cè)試軟件版本切換,或業(yè)務(wù)節(jié)點(diǎn)升級(jí)出現(xiàn)異常執(zhí)行版本回退操作,實(shí)際上就是正常安裝舊版程序包,但需要同時(shí)--oldpackage --force兩個(gè)微調(diào)選項(xiàng),升級(jí)后兩個(gè)版包并存??梢愿鶕?jù)實(shí)際需要決定是否卸載新版包。
rpm -ivh tree-1.6.0-10.el7.x86_64.rpm --oldpackage --force
小提示: 如果只有--oldpackage會(huì)提示文件沖突,需同時(shí)指定 --replacefiles進(jìn)行文件替換。此時(shí)通過rpm -q查詢會(huì)發(fā)現(xiàn)兩個(gè)版本軟件并存的現(xiàn)象,但后安裝的應(yīng)用程序文件覆蓋了原有應(yīng)用程序文件,軟件確實(shí)降級(jí)成功。原因:-i是安裝操作會(huì)將新的軟件版本信息注冊(cè)到rpm數(shù)據(jù)庫。因此卸載、查詢操作需要加版本號(hào)才可以。
5.程序包查詢
坦白說個(gè)人認(rèn)為rpm包管理工具查詢功能在工作中用得最多了,當(dāng)然yum也有查詢功能,但是不大眾的包還得yum與rpm配合來用
語法:rpm {-q|--query} [select-options] [query-options]
常用選項(xiàng)組合
? rpm -q httpd 查詢是系統(tǒng)是否已經(jīng)安裝某包,多版并存時(shí)需指定版本號(hào)
? rpm -q httpd-tools --scripts查看安裝包內(nèi)的腳本文件
? rpm -qa|grep httpd all查看所有已安裝的包并過濾
? rpm -qc httpd cofig查看某應(yīng)用的配置文件位置
? rpm -qd httpd doc查看某應(yīng)用的幫助文檔位置
? rpm-qf /etc/passwd 查看某文件來自于哪個(gè)rpm包
? rpm -qi setup-2.8.71-10.el7.noarch查看已安裝包的詳細(xì)信息
? rpm -ql httpd-tools 查看已安裝包產(chǎn)生的文件列表
? rpm -qpl yum-4.0.9.2-5.el8.noarch.rpm 查看未安裝的rpm包內(nèi)文件列表
? rpm -qpi yum-4.0.9.2-5.el8.noarch.rpm 查看未安裝的rpm包的元數(shù)據(jù)信息
功能查詢
這個(gè)能力查詢功能是最長用的了
? --whatprovides CAPABILITY:查詢指定的CAPABILITY由哪個(gè)包所提供
? --whatrequires CAPABILITY:查詢指定的CAPABILITY被哪個(gè)包所依賴
? -R:查詢指定的程序包所依賴的CAPABILITY
技巧舉例:
? rpm -q httpd --provides:列出httpd提供的CAPABILITY(能力)
? rpm -q httpd --whatprovides:查詢httpd這個(gè)能力是來自于哪個(gè)程序包
? rpm -q bash --whatprovides 查詢bash命令是由哪個(gè)包提供的
? rpm -q bash --whatrequires 查詢都有哪些包依賴bash這個(gè)能力
6.程序包校驗(yàn)
這個(gè)包校驗(yàn)雖然簡單,但在實(shí)際應(yīng)用過程中可要注意涉及安全問題,尤其是現(xiàn)在網(wǎng)絡(luò)ISP為了提供用戶體驗(yàn)可能出現(xiàn)域名劫持,或HTTPS階段代理,如果我們使用yum下載安裝rpm包的過程中出現(xiàn)了域名劫持,然后yum客戶端倉庫配置文件配置了gpgcheck=1,gpgkey也配置了網(wǎng)上獲取,則如果yum源服務(wù)器域名被劫持了,那么在第一次使有yum的時(shí)候非法的key會(huì)被自動(dòng)導(dǎo)入到系統(tǒng),即使開了gpgcheck功能也是枉然。這里有個(gè)知識(shí)點(diǎn)要先確實(shí)一下:數(shù)據(jù)簽名技術(shù),rpm包驗(yàn)證也就是基本數(shù)據(jù)簽名技術(shù)。與微軟的數(shù)字簽名技術(shù)是一樣的
大概原理是將官方對(duì)rmp包做hash得到散列值A(chǔ),然后用私鑰加密散列值得到的密文信息做為額外屬性攜帶在rpm包中,客戶端拿到rpm包后將rpm包的數(shù)據(jù)部分做hash計(jì)算得到散列值B,然后再用官方發(fā)而的公鑰解密rpm包中攜帶的密文得到原始散列A,如果A=B則認(rèn)為該rpm包從官方發(fā)布至今未做任何修改,并且一定是官方發(fā)布的,否則公鑰無法解密密文得到A。
官方發(fā)布的安裝包采用的是非對(duì)稱密鑰加密技術(shù),私鑰加密碼公鑰解密-數(shù)字簽名的技術(shù),公鑰導(dǎo)入系統(tǒng)后再安裝官方的rpm就不會(huì)出現(xiàn)簽名告警了,如果系統(tǒng)中沒有導(dǎo)入官方公鑰或已經(jīng)導(dǎo)入公鑰但每次安裝rpm包都提供簽名告警那就真要注意了
公鑰管理:
官方的公鑰隨光盤攜帶,需要導(dǎo)入系統(tǒng):
? 安裝公鑰:rpm --import RPM-GPG-KEY-CentOS-7
? 搜索公鑰:rpm -qa "*pubkey*"
? 查看公鑰:rpm -qi gpg-pubkey-f4a80eb5-53a7ff4b
? CentOS中存儲(chǔ)位置為:/etc/pki/rpm-gpg
? 卸載公鑰:rpm -e gpg-pubkey
校驗(yàn)程序文件屬性變化:從系統(tǒng)安裝到查詢時(shí)間點(diǎn)開始計(jì)算發(fā)生變化就會(huì)顯示打上下標(biāo)記
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
rpm -V tree
rpm解包操作
rpm2cpio /misc/cd/BaseOS/Packages/tree-1.7.0-15.el8.x86_64.rpm |cpio -idv ./
三、rpm微調(diào)選項(xiàng)
select-options 作為包查詢、校驗(yàn)操作的微調(diào)選項(xiàng)
[PACKAGE_NAME]
[-a,--all [SELECTOR]] [-f,--file FILE]
[-g,--group GROUP] {-p,--package PACKAGE_FILE]
[--hdrid SHA1]
[--pkgid MD5]
[--tid TID]
[--querybynumber HDRNUM]
[--triggeredby PACKAGE_NAME]
[--whatprovides CAPABILITY] 查詢指定的CAPABILITY由哪個(gè)程序包提供
[--whatrequires CAPABILITY] 查詢哪些程序包依賴此CAPABILITY
[--whatrecommends CAPABILITY]
[--whatsuggests CAPABILITY]
[--whatsupplements CAPABILITY]
[--whatenhances CAPABILITY]
[--whatobsoletes CAPABILITY]
[--whatconflicts CAPABILITY]
query-options 作為包查詢操作的微調(diào)選項(xiàng)
General: 常規(guī)查詢選項(xiàng)
[--changelog] 顯示包的更改記錄
[--changes]
[--dupes]
[-i,--info]顯示包信息
[--last]
[--qf,--queryformat QUERYFMT]
[--xml]
Dependencies:
[--conflicts]
[--enhances]
[--obsoletes]
[--provides]
[--recommends]
[-R,--requires]
[--suggests]
[--supplements]
Files:文件類查詢
[-c,--configfiles] 查詢已安裝包的配置文件存儲(chǔ)位置 例:rpm -qc bash
[-d,--docfiles] 查詢已安裝包的幫助文檔存儲(chǔ)位置 例:rpm -qd bash
[--dump]
[--fileclass] 查詢已安裝包相關(guān)文件的類型 rpm -q bash --fileclass
[--filecolor]
[--fileprovide]
[--filerequire] rpm -q yum --filerequire
[--filecaps]
[--filesbypkg]
[-l,--list] 查看包相關(guān)的文件列表
[-s,--state] 查看包相關(guān)的文件狀態(tài)
[--noartifact]
[--noghost]
[--noconfig
Scripts and triggers:
[--filetriggers]
[--scripts] 查看包安裝前后執(zhí)行的腳本 rpm -q bash --scripts
[--triggers,--triggerscripts]
verify-options
[--nodeps] 不校驗(yàn)軟件的依賴關(guān)系
[--nofiles]
[--noscripts]
[--nodigest]
[--nosignature] 不校驗(yàn)數(shù)字簽名
[--nolinkto]
[--nofiledigest]
[--nosize]
[--nouser]
[--nogroup]
[--nomtime]
[--nomode]
[--nordev]
[--nocaps]
install-options
[--allfiles] 所有包
[--badreloc]
[--excludepath OLDPATH]
[--excludedocs]
[--force] 強(qiáng)制安裝,--replacefiles和—replacepkgs的綜合體
[-h,--hash]
[--ignoresize]
[--ignorearch] 忽略硬件架構(gòu)平臺(tái)
[--ignoreos] 忽略操作系統(tǒng)
[--includedocs]
[--justdb] 更新數(shù)據(jù)庫,當(dāng)不變動(dòng)任何文件
[--nodeps] 忽略依賴關(guān)系直接安裝
[--nodigest] 不校驗(yàn)包完整性
[--noplugins]
[--nocaps]
[--noorder]
[--noverify]
[--nosignature] 忽略驗(yàn)數(shù)字簽名,用于安裝第三方包
[--noscripts] 不執(zhí)行軟件包內(nèi)的安裝前后腳本
[--notriggers]
[--oldpackage] 用于軟件包降級(jí)
[--percent] 安裝時(shí)顯示完成度百分比
[--prefix NEWPATH] 指定安裝目錄,把文件放到指定的目錄下
[--relocate OLDPATH=NEWPATH] 把本來會(huì)放到原目錄下的文件改放到新目錄。
[--replacefiles] 替換文件
[--replacepkgs] 替換包
[--test] 測(cè)試安裝,但不真正執(zhí)行安裝,即dry run模式
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。