軟件包管理
包管理器
二進制應用程序的組成部分:
二進制文件、庫文件、配置文件、幫助文件
程序包管理器:
debian: deb文件, dpkg包管理器
redhat: rpm文件, rpm包管理器
rpm: Redhat Package Manager
RPM Package Manager
包命名
源代碼: name-VERSION.tar.gz|bz2|xz
VERSION: major.minor.release
rpm包命名方式:
name-VERSION-release.arch.rpm
例: bash-4.2.46-19.el7.x86_64.rpm
VERSION: major.minor.release
release: release.OS
常見的arch:
x86: i386, i486, i586, i686
x86_64: x64, x86_64, amd64
powerpc: ppc
跟平臺無關: noarch
包命名和工具
包:分類和拆包
Application-VERSION-ARCH.rpm: 主包
Application-devel-VERSION-ARCH.rpm 開發子包
Application-utils-VERSION-ARHC.rpm 其它子包
Application-libs-VERSION-ARHC.rpm 其它子包
包之間:可能存在依賴關系,甚至循環依賴,解決依賴包管理工具:
yum: rpm包管理器的前端工具
apt-get: deb包管理器前端工具
zypper: suse上的rpm前端管理工具
dnf: Fedora 18+ rpm包管理器前端管理工具
庫文件
查看二進制程序所依賴的庫文件(必須要寫絕對路徑否則會報錯):
ldd /PATH/TO/BINARY_FILE
管理及查看本機裝載的庫文件:/sbin/ldconfig
ldconfig
-p: 顯示本機已經緩存的所有可用庫文件
名及文件路徑映射關系
配置文件: /etc/ld.so.conf, /etc/ld.so.conf.d/*.conf
緩存文件: /etc/ld.so.cache
程序包管理器:
功能:將編譯好的應用程序的各組成文件打包一個或幾個程序包文件,從而方便快捷地實現程序包的安裝、卸載、查詢、升級和校驗等管理操作
1、包文件組成 (每個包獨有)
RPM包內的文件
RPM的元數據,如名稱,版本,依賴性,描述等
安裝或卸載時運行的腳本
2、數據庫(公共)
程序包名稱及版本 : 依賴關系 、功能說明 、 包安裝后生成的各文件路徑及校驗碼信息 、 程序包的來源
管理程序包的方式:
使用包管理器: rpm
使用前端工具: yum, dnf
獲取程序包的途徑:
(1) 系統發版的光盤或官方的服務器;
CentOS鏡像:
https://www.centos.org/download/
(2) 項目官方站點
程序包的來源
(3) 第三方組織:
Fedora-EPEL:
Extra Packages for Enterprise Linux
Rpmforge:RHEL推薦,包很全
搜索引擎:
(4) 自己制作
注意:檢查其合法性: 來源合法性,程序包的完整性
===================================================================================================================================
rpm包管理
以CentOS 為例 ,CentOS系統上使用rpm命令管理程序包:
安裝、卸載、升級、查詢、校驗、數據庫維護
安裝:
rpm {-i|–install} [install-options] PACKAGE_FILE…
-v: verbose
-vv:
-h: 以#顯示程序包管理執行進度
rpm -ivh PACKAGE_FILE …
(PS:安裝包的時候經常加ivh 顯示安裝詳細信息以及安裝進度)
rpm包安裝
[install-options]
–test: 測試安裝,但不真正執行安裝; dry run模式(但在沒有導入公鑰時,會報錯)
–nodeps:忽略依賴關系
–replacepkgs | replacefiles
–nosignature: 不檢查來源合法性
–nodigest:不檢查包完整性
–noscipts:不執行程序包腳本片斷
%pre: 安裝前腳本; –nopre
%post: 安裝后腳本; –nopost
%preun: 卸載前腳本; –nopreun
%postun: 卸載后腳本; –nopostun
rpm包升級
升級:
rpm {-U|–upgrade} [install-options] PACKAGE_FILE…
rpm {-F|–freshen} [install-options] PACKAGE_FILE…
upgrade:安裝有舊版程序包,則“升級”;如果不存在舊版程序包,則“安裝”(能當安裝使用)
freshen:安裝有舊版程序包,則“升級”;如果不存在舊版程序包,則不執行升級操作(只能當升級使用)
rpm -Uvh PACKAGE_FILE …
rpm -Fvh PACKAGE_FILE …
–oldpackage:降級
–force: 強行升級
升級注意項
(1) 不要對內核做升級操作; Linux支持多內核版本并存,因此,對直接安裝新版本內核
(2) 如果原程序包的配置文件安裝后曾被修改,升級時,新版本的提供的同一個配置文件并不會直接覆蓋老版本的配置文件,而把新版本的文件重命名(FILENAME.rpmnew)后保留
包查詢
rpm {-q|–query} [select-options] [query-options] 準確的包名
[select-options]
-a: 所有包(已經安裝在系統上的所有包)
-f: 查看指定的文件由哪個程序包安裝生成
-l :相當于 ls 查看程序安裝完之后的文件
-p rpmfile:針對尚未安裝的程序包文件做查詢操作;(后跟明確的包名)
–whatprovides CAPABILITY:查詢指定的CAPABILITY
由哪個包所提供(查看程序的依賴文件)
–whatrequires CAPABILITY:查詢指定的CAPABILITY被哪個包所依賴(查該程序文件被哪一個程序所依賴)
rpm2cpio 包文件|cpio –itv 預覽包內文件
rpm2cpio 包文件|cpio –id “ *.conf” 釋放包內文件 (*是指包內所有未見,可用-itv預覽包內文件,按需釋放,但用次方法釋放文件,需要注意元數據的變化,如屬主屬組等)(注意:釋放的路徑,按需填寫)
(PS:也可以釋放在當前路徑,然后cp到所需位置,不過要注意元數據的變化)
[query-options]
–changelog:查詢rpm包的changelog(查更新版本,更新日志)
-c: 查詢程序的配置文件
-d: 查詢程序的文檔
-i: information
-l: 查看指定的程序包安裝后生成的所有文件;
–scripts:程序包自帶的腳本片斷
-R: 查詢指定的程序包所依賴的CAPABILITY;
–provides: 列出指定程序包所提供的CAPABILITY;
卸載:(安裝有依賴性,卸載也有依賴性,rpm無法解決依賴性,需要手動一個一個安裝)
rpm {-e|–erase} [–allmatches] [–nodeps] [–noscripts] [–notriggers] [–test] PACKAGE_NAME …
–allmatches : 全部卸載
–nodeps :不考慮依賴性
–noscripts :不執行腳本
–notriggers :不觸發另一個相關動作(如腳本等)
–test :只作測試 ,不會卸載
包校驗
rpm {-V|–verify} [select-options] [verify-options]
檢測程序安裝完成后的完整性
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
包來源合法性驗正及完整性驗正: (signature簽名等 );包被不合法修改過,或者本機無檢測包合法性的機制,則會報錯
/etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 或在光盤下 ./CentOS 7 x86_64/RPM-GPG-KEY-CentOS-7
完整性驗正: SHA256
來源合法性驗正: RSA
公鑰加密:
對稱加密:加密、解密使用同一密鑰;
非對稱加密:密鑰是成對兒的
public key: 公鑰,公開所有人
secret key: 私鑰, 不能公開
導入所需要公鑰:
rpm -K|checksig rpmfile 檢查包的完整性和簽名
rpm –import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
CentOS 7發行版光盤提供: RPM-GPG-KEY-CentOS-7
rpm -qa gpg-pubkey*
rpm數據庫
數據庫重建:
/var/lib/rpm
rpm {–initdb|–rebuilddb}
initdb: 初始化
如果事先不存在數據庫,則新建之;否則,不執行任何操作
(PS:新建的數據庫里邊沒有任何信息,相當于一個空表.在新建數據庫之前安裝了tree,但后來數據庫丟失,新建數據庫后,若要刪除tree,系統會提示沒有安裝tree,因為新建的數據庫是空表!!!
新建數據庫要謹慎小左)
rebuilddb:重建已安裝的包頭的數據庫索引目錄.只是新建索引目錄文件;無論當前存在與否,rebuilddb都會直接重新創建數據庫
=============================================================================================================================
yum
CentOS: yum, dnf
YUM: Yellowdog Update Modifier, rpm的前端程序,用來解決軟件包相關依賴性,可以在多個庫之間定位軟件包,up2date的替代工具
yum repository: yum repo,存儲了眾多rpm包,以及包的相關的元數據文件(放置于特定目錄repodata下)
文件服務器:
ftp://
http://
file:///
yum客戶端配置文件:
/etc/yum.conf:為所有倉庫提供公共配置
/etc/yum.repos.d/*.repo:為倉庫的指向提供配置
倉庫指向的定義:(可以自定義文件指向路徑)
[repositoryID]
name=Some name for this repository
baseurl=url://path/to/repository/ #倉庫的訪問路徑
enabled={1|0} # 1 :表示啟用 ; 0 : 表示不啟用
gpgcheck={1|0} # 1 :驗證gpg ; 0 : 表示不驗證gpg
gpgkey=URL #公鑰路徑,可以是本地,也可以是服務器端路徑,也可以不填
enablegroups={1|0} #是否啟用包組信息
failovermethod={roundrobin|priority} #多個url時如何選擇;roundrobin 隨機選擇;priority默認選擇
cost= 默認為1000 #定義此倉庫開銷,默認為10000
yum命令的用法:
yum [options] [command] [package …]
yum-config-manager –disable “倉庫名" 禁用倉庫
yum-config-manager –enable “倉庫名” 啟用倉庫
顯示倉庫列表:
repolist [all|enabled|disabled]
顯示程序包:
list
# yum list [all | glob_exp1] [glob_exp2] […]
# yum list {available|installed|updates} [glob_exp1]
[…]
安裝程序包:
install package1 [package2] […]
reinstall package1 [package2] […] (重新安裝)
升級程序包:
update [package1] [package2] […]
downgrade package1 [package2] […] (降級)
檢查可用升級:
check-update
卸載程序包:
remove | erase package1 [package2] […]
查看程序包information:
info […]
查看指定的特性(可以是某文件)是由哪個程序包所提供:
provides | whatprovides feature1 [feature2] […]
清理本地緩存:
clean [ packages | metadata | expire-cache |rpmdb | plugins | all ]
構建緩存:
makecache
搜索: search string1 [string2] […]
以指定的關鍵字搜索程序包名及summary信息
查看指定包所依賴的capabilities:
deplist package1 [package2] […]
查看yum事務歷史:
history [info|list|packages-list|packages-info|
summary|addon-info|redo|undo|
rollback|new|sync|stats]
yum history
yum history info 6
yum history undo 6
日志 : /var/log/yum.log
============================================================================================================
附上文末彩蛋:
編寫腳本/root/bin/copycmd.sh
(1) 提示用戶輸入一個可執行命令名稱;
(2) 獲取此命令所依賴到的所有庫文件列表
(3) 復制命令至某目標目錄(例如/mnt/sysroot)下的對應路徑下;
如:/bin/bash ==> /mnt/sysroot/bin/bash
/usr/bin/passwd==> /mnt/sysroot/usr/bin/passwd
(4) 復制此命令依賴到的所有庫文件至目標目錄下的對應路徑下:
如:/lib64/ld-linux-x86-64.so.2 ==> /mnt/sysroot/lib64/ld-linux-x86-64.so.2
(5)每次復制完成一個命令后,不要退出,而是提示用戶鍵入新的要復制的命令,并重復完成上述功能;直到用戶輸入quit退出
[root@localhost bin]# cat copycmd.sh #!/bin/bash # copy() { while [[ $# -ge 1 ]];do cp $1 /testdir/bin/sysroot/dir_$cmd echo "$1 copy complate" shift #運用shift參數吐息,優化腳本 done } while true ;do read -p "this scrip will copy the command what you want : " cmd if which $cmd &> /dev/null ;then mkdir /testdir/bin/sysroot/dir_$cmd cmdlist=`whereis $cmd |sed -r "s@$cmd:(.*)@\1@"` lddlist=$(ldd `which $cmd | tr -d '\t'|grep "/.*"` | tr ' ' '\n' |grep "/.*") #####注意反引號 ` 與$(cmd)的運用; 反引號 ` 用多了,會看得眼睛亂;還有 $(cmd)是命令引用 ;而$((算術運算式)) 是算術運算符 copy $cmdlist copy $lddlist else echo "wrong command ,try again" fi done
1、編寫服務腳本/root/bin/testsrv.sh,完成如下要求
(1) 腳本可接受參數:start, stop, restart, status
(2) 如果參數非此四者之一,提示使用格式后報錯退出
(3) 如是start:則創建/var/lock/subsys/SCRIPT_NAME, 并顯示“啟動成功”
考慮:如果事先已經啟動過一次,該如何處理?
(4) 如是stop:則刪除/var/lock/subsys/SCRIPT_NAME, 并顯示“停止完成”
考慮:如果事先已然停止過了,該如何處理?
(5) 如是restart,則先stop, 再start
考慮:如果本來沒有start,如何處理?
(6) 如是status, 則如果/var/lock/subsys/SCRIPT_NAME文件存在,則顯示“SCRIPT_NAMEis running…”
如果/var/lock/subsys/SCRIPT_NAME文件不存在,則顯示“SCRIPT_NAME is stopped…”
其中:SCRIPT_NAME為當前腳本名
[root@localhost bin]# cat testsrv.sh #!/bin/bash # start() { if [[ ! -a /testdir/bin/subsys/$0 ]];then touch /testdir/bin/subsys/$0 && echo -e "\033[32mstart succeefully\033[0m" else echo -e "\033[31m$0 is running...\033[0m" fi } stop() { if [[ -a /testdir/bin/subsys/$0 ]];then rm /testdir/bin/subsys/$0 echo -e "\033[32mstop succeefully\033[0m" else echo -e "\033[31m$0 has stoped...\033[0m" fi } restart() { if [[ -a /testdir/bin/subsys/$0 ]];then rm /testdir/bin/subsys/$0 && touch /testdir/bin/subsys/$0 echo -e "\033[32mrestart succeefully\033[0m" else echo -e "\033[31mrestart unsucceefully\033[0m" fi } status() { if [[ -a /testdir/bin/subsys/$0 ]];then echo -e "\033[32m$0 is running...\033[0m" else echo -e "\-33[32m$0 has stopped...\033[0m" fi } ######以上參數可以寫在另一個文件中,然后在本腳本中調用.(注意用. ./file 或者 source ./file 而不是bash ./file)####### PS3="this script will help you deal something , please enter you chose : " select chose in start stop restart status do case $chose in start) start ;; stop) stop ;; restart) restart ;; status) status ;; *) echo "wrong options , try again" ;; esac done
原創文章,作者:hunter,如若轉載,請注明出處:http://www.www58058.com/38775