Linux 基礎學習篇 - Fedora Core 4

第二十章、 RPM 與 SRPM 套件管理員 - for Fedora Core 4

利用 RPM 來管理整個 Linux 的套件,同時以一個簡單的範例來操縱 SRPM 的建立

最近更新時間: 2005/10/03

本文資料主要針對 Fedora Core 4 的系統進行說明, Fedora Core 1 主要是由 Red Hat Linux 9 改版而來, 這個 Red Hat Linux 9 並不是當前大家聽到的 RHEL 喔!那是在 RHEL 出現之前的產品,基本上是在 2003 年以前的作品了!Fedora Core 4 則是在 2005 年 6 月份釋出,使用的核心是 2.6.11 版,當時是很紅的一個作品!只是生命週期太短,所以用這個 Fedora 系列來介紹 Server, 當時的決定確實有點莫名其妙了...

建議您前往本站查詢最新版本的 Linux distribution 文章來閱讀,比較不會浪費時間。那為何還需要編輯 Fedora Core 4 的資料呢? 鳥哥只想要做個自己曾經撰寫過的文件內容保存而已囉! ^_^!最新文章請前往鳥站首頁查閱囉!

在上一章當中,我們介紹了以 Tarball 的方式來安裝我們的套件,同時也說明了 Source code 與執行檔之間的關係。不過,如果每次安裝套件都需要進行編譯的動作,那麼實在很沒效率!這個時候,由 Red Hat 公司所開發出來的套件管理程式( Red Hat Package Manager, RPM )可就幫了大忙了!RPM 除了可以用來安裝套件之外,還可以進行查詢、升級、反安裝、以及其他驗證等等的功能, 這些功能讓我們在管理系統的套件上,更顯的方便呢!此外,我們也可以利用 RPM 的原理來『自行創造自己的 RPM 檔案』呢!

由於 RPM 實在是太好用了,目前主要的 Linux distributions 都是使用 RPM 來管理他們的套件,例如 Red Hat 系統 (含 Fedora ), SuSE 與改版後的 Mandriva ,所以,您不能不知道 RPM 是什麼東西?該如何利用他,以及熟悉相關的功能!趕緊來參詳參詳!

前言

在前一章我們提到以原始碼的方式來安裝套件,也就是利用廠商釋出的 Tarball 來進行套件與程式的安裝。不過,您應該很容易發現,那就是每次安裝套件都需要設定作業系統、 設定編譯參數、實際的編譯、最後還要依據個人喜好的方式來安裝套件到定位。 這過程是真的很麻煩的,而且對於不熟整個系統的朋友來說,還真是累人啊!

那有沒有想過,如果我的 Linux 系統與廠商的系統一模一樣,那麼在廠商的系統上面編譯出來的執行檔, 自然也就可以在我的系統上面跑囉!也就是說,廠商先在他們的系統上面編譯好了我們使用者所需要的套件, 然後將這個編譯好的可執行的套件直接釋出給使用者來安裝,如此一來,由於我們本來就使用廠商的 Linux distribution ,所以當然系統是一樣的,那麼使用廠商提供的編譯過的可執行檔就沒有問題啦! 說的比較白話一些,那就是利用類似 Windows 的安裝方式,由程式開發者直接在已知的系統上面編譯好,再將該程式直接給使用者來安裝,如此而已。

那麼如果在安裝的時候還可以加上一些與這些程式相關的資訊,將他建立成為資料庫, 那不就可以進行安裝、反安裝、升級與驗證等等的相關功能囉( 類似 Windows 底下的『新增移除程式』 )?!確實如此,在 Linux 上面至少就有兩種常見的這方面的套件管理員,分別是 RPM 與 Debian 的 dpkg ,其中又以 RPM 更常見。所以底下我們就來介紹一下 RPM 這個咚咚囉!

什麼是 RPM 與 SRPM

RPM 全名是『 RedHat Package Manager 』簡稱則為 RPM 啦!顧名思義,當初這個套件管理的程式是由 Red Hat 這家公司發展出來的, 但其實在很多的其他套件也有相類似的套件管理程式。不過由於 RPM 使用上很方便,所以就成了目前最熱門的套件管理程式啦!

那麼什麼是 RPM 呢?說的簡單一點, RPM 是以一種資料庫記錄的方式來將你所需要的套件安裝到你的 Linux 主機的一套管理程式。他最大的特點就是將您要安裝的套件先編譯過( 如果需要的話 )並且打包好了,透過包裝好的套件裡頭預設的資料庫記錄, 記錄這個套件要安裝的時候必須要的相依屬性模組( 就是你的 Linux 主機需要先存在的幾個必須的套件 ),當安裝在你的 Linux 主機時, RPM 會先依照套件裡頭的紀錄資料查詢 Linux 主機的相依屬性套件是否滿足, 若滿足則予以安裝,若不滿足則不予安裝。那麼安裝的時候就將該套件的資訊整個寫入 RPM 的資料庫中,以便未來的查詢、驗證與反安裝!這樣一來的優點是:
  1. 由於已經編譯完成並且打包完畢,所以安裝上很方便( 不需要再重新編譯 );
  2. 由於套件的資訊都已經記錄在 Linux 主機的資料庫上,很方便查詢、升級與反安裝;
但是這也造成很大的困擾,由於 RPM 程式是已經包裝好的資料,也就是說, 裡面的資料已經都『編譯完成』了!所以, 安裝的時候一定需要當初安裝時的主機環境才能安裝 ,也就是說,當初建立這個套件的安裝環境必須也要在你的主機上面出現才行!例如 rp-pppoe 這個 ADSL 撥接套件,他必須要在 ppp 這個套件存在的環境下才能進行安裝!如果你的主機並沒有 ppp 這個套件,那麼很抱歉,除非您先安裝 ppp 否則 rp-pppoe 就是不讓你安裝的( 當然您可以強制安裝,但是通常都會有點問題發生就是了! )。

所以,通常不同的 distribution 所釋出的 RPM 檔案,並不能用在其他的 distributions 裡面,舉例來說, Fedora 釋出的 RPM 檔案,通常無法直接在 Mandriva 上面進行安裝的,更有甚者, 不同版本之間也無法互通,例如 Fedora Core 4 的 RPM 檔案就無法直接套用在 FC3 上面!因此,這樣可以發現他的缺點是:
  1. 安裝的環境必須與打包時的環境需求一致或相當;
  2. 需要滿足套件的相依屬性需求;
  3. 反安裝時需要特別小心,最底層的套件不可先移除,否則可能造成整個系統的問題!
那怎麼辦?呵呵!還好,還有 SRPM 這個東西! SRPM 是什麼呢?顧名思義,他是 Source RPM 的意思,也就是這個 RPM 檔案裡面含有原始碼( Source Code )哩!特別注意的是,這個 SRPM 所提供的套件內容『並沒有經過編譯』, 他提供的是原始碼喔!

通常 SRPM 的副檔名是以 ***.src.rpm 這種格式來命名的 。不過,既然 SRPM 提供的是原始碼,那麼為什麼我們不使用 Tarball 直接來安裝就好了?!這是因為 SRPM 雖然內容是原始碼, 但是他仍然含有該套件所需要的相依性套件說明、以及所有 RPM 檔案所提供的資料,同時,他與 RPM 不同的是,他也提供了參數設定檔( 就是 configure 與 makefile 啦! )。所以,如果我們下載的是 SRPM ,那麼要安裝該套件時,RPM 套件管理員將會(1)先將該套件以 RPM 管理的方式編譯,(2)然後將編譯完成的 RPM 檔案安裝到 Linux 系統當中。與 RPM 檔案相比, SRPM 多了一個重新編譯的動作, 而且 SRPM 編譯完成會產生 RPM 檔案

怪了,怎麼 SRPM 這麼麻煩吶!還要重新編譯一次,那麼我們直接使用 RPM 來安裝不就好了!?通常一個套件在釋出的時候,都會同時釋出該套件的 RPM 與 SRPM 。我們現在知道 RPM 檔案必須要在相同的 Linux 環境下才能夠安裝,而 SRPM 既然是原始碼的格式,自然我們就可以透過修改 SRPM 內的參數設定檔,然後重新編譯產生能適合我們 Linux 環境的 RPM 檔案,如此一來,不就可以將該套件安裝到我們的系統當中,而不必與原作者打包的 Linux 環境相同了?這就是 SRPM 的用處了!

什麼是 i386, i586, i686, noarch

好啦!現在我們已經知道 RPM 與 SRPM 的格式了,分別為:
xxxxxxxxx.rpm   <==RPM 的格式,已經經過編譯且包裝完成的 rpm 檔案;
xxxxx.src.rpm   <==SRPM的格式,包含未編譯的原始碼資訊。
那麼我們怎麼知道這個套件的版本、適用的平台、打包的次數呢?呵呵!只要透過檔名就可以知道了!例如 rp-pppoe-3.1-5.i386.rpm 這的檔案的意義為:
rp-pppoe -        3.1    -     5        .i386        .rpm
套件名稱   套件的版本資訊 釋出的次數 適合的硬體平台 副檔名
除了後面適合的硬體平台與副檔名外,主要是以『-』來隔開各個部分, 這樣子可以很清楚的發現該套件的名稱、版本資訊、打包次數與操作的硬體平台! 好了,來談一談每個不同的地方吧:
  • 套件名稱
    當然就是每一個套件的名稱了!上面的範例就是 rp-pppoe 。

  • 版本資訊
    每一次更新版本就需要有一個版本的資訊,否則如何知道這一版是新是舊? 這裡通常又分為主版本跟次版本,以上面為例,主版本為 3 ,在主版本的架構下更動部分原始碼內容,而釋出一個新的版本,就是次版本啦! 以上面為例,就是 1 囉!

  • 釋出版本次數
    也就是編譯的次數啦!那麼為何需要重複的編譯呢? 這是由於同一版的套件中,可能由於有某些 bug 或者是安全上的顧慮,所以必須要重新設定當初打包時候的設定參數, 設定完成之後重新編譯並打包成 RPM 檔案!因此就有不同的打包數出現了!( 註:這個時候原始碼其實還是 3.1 那個版本,只是下達編譯時的參數不同而已! )

  • 操作硬體平台
    這是個很好玩的地方,由於 RPM 可以適用在不同的操作平台上, 但是由於不同的平台設定的參數還是有所差異性!並且,我們可以針對比較高階的 CPU 來進行最佳化參數的設定,所以就有所謂的 i386, i586, i686 與 noarch 等的檔案名稱出現了!

    平台名稱適合平台說明
    i386 幾乎適用於所有的 x86 平台,不論是舊的 pentum 或者是新的 pentum-IV 與 K7 系列的 CPU等等,都可以正常的工作!那個 i 指的是 Intel 相容的 CPU 的意思,至於 386 不用說,就是 CPU 的等級啦!
    i586 就是 586 等級的電腦,那是哪些呢?包括 pentum 第一代 MMX CPU, AMD 的 K5, K6 系列 CPU ( socket 7 插腳 ) 等等的 CPU 都算是這個等級;
    i686 在 pentun II 以後的 Intel 系列 CPU ,及 K7 以後等級的 CPU 都屬於這個 686 等級!
    noarch 就是沒有任何硬體等級上的限制。一般來說,這種類型的 RPM 檔案,裡面應該沒有 binary file 存在。

    需要額外說明的是, i386 的檔案可以在任何的機器上面安裝, 不論是 586 或者是 686 的機器,但是 i686 則不一定可以使用於 386 或者是 586 的硬體上面,這是因為 i686 的 RPM 檔案在編譯的時候,主要是針對 686 硬體等級的 CPU 來進行最佳化編譯,而 386/586 等級的硬體可能由於無法支援該最佳化參數, 所以無法使用呢!另外,在 686 的機器上使用 i686 的檔案會比使用 i386 的檔案,效能可能比較好一些!無論如何,使用 i386 應該就是比較沒有問題的啦!另外,由於不同的 distirbution 會有不同的環境與函式庫,所以在 i386 之後也有可能會額外再加上該套件的簡寫!

RPM 的優點

RPM 有以下的優點:
  • RPM 檔案本身為已經編譯過的 binary 檔案,可以讓 client 端的使用者免除重新編譯的困擾;
  • RPM 檔案在被安裝之前,RPM 會先檢查系統的硬碟容量、作業系統版本等,可避免檔案被安裝錯誤;
  • RPM 檔案本身提供套件版本資訊、相依屬性套件名稱、套件用途說明、套件所含檔案等資訊,便於瞭解套件;
  • RPM 管理的方式使用資料庫記錄 RPM 檔案的相關參數,便於升級、移除、查詢與驗證。
為什麼 RPM 在使用上很方便呢?我們前面提過, RPM 這個套件管理員所處理的套件,是由套件提供者在特定的 Linux 作業平台上面將該套件編譯完成,並且打包好,那使用者只要拿到這個打包好的套件, 然後將裡頭的檔案放置到應該要擺放的目錄,不就完成安裝囉?!對啦!就是這樣! 但是有沒有想過,我們在前一章原始碼與 Tarball 裡面提過的,有些套件是有相關性的,例如要安裝網路卡驅動程式,就得要有 kernel source 與 gcc 及 make 等套件。那麼我們的 RPM 套件是否一定可以安裝完成呢?! 如果該套件安裝之後,卻找不到他相關的前驅套件,那不是挺麻煩的嗎?因為安裝好的套件也無法使用啊!

為了解決這種具有相關性套件之間的問題,就是所謂的套件相依屬性,RPM 就在提供套件打包的檔案時,同時加入一些訊息登錄的功能,這些訊息包括套件的版本、 打包套件者、相依屬性的套件、套件的功能說明、該套件的所有檔案與目錄紀錄、等等,然後在 Linux 系統上面亦建立一個 RPM 套件資料庫( database ),如此一來,當您要安裝某個以 RPM 型態提供的套件時,在安裝的過程中, RPM 會去檢驗一下資料庫裡面是否已經存在相關的套件了, 如果資料庫顯示不存在,那麼這個 RPM 檔案『預設』就不能安裝( 會顯示一些錯誤訊息 )。呵呵!沒有錯,這個就是 RPM 類型的檔案最為人所詬病的『 套件的屬性相依』問題啦!

RPM 屬性相依的克服方式

雖然 RPM 有套件屬性相依的問題,但是 RPM 的優點實在是比缺點要好的多,所以很多使用者還是偏好使用 RPM 來管理自己的套件,在這樣的情況下,如何解決 RPM 的屬性相依問題呢?最簡單的方式就是在安裝 RPM 檔案的時候,發生套件相依的問題時,手動去下載前驅套件,先安裝好這些套件, 然後再安裝最終想要安裝的套件即可。但是,如此一來很花費使用者的精神與時間,挺麻煩的啦! 有沒有比較快速的方法呢?

呵呵!有的,由於 RPM 類型的檔案裡面含有屬性相依的訊息存在,如果我們可以透過分析這些訊息, 再讓程式自行去尋找未安裝的前驅套件,並事先加以安裝,如此一來不就解決了屬性相依的困擾了嗎?! 沒錯!是這樣!這就是目前所謂的 urpmi/apt/yum 等服務的由來啦!這些服務都是透過分析 RPM 檔案的相依資訊,然後自行取得相依屬性套件, 自行完成安裝的動作,呵呵!相當的方便呢!這些資訊我們會在 伺服器架設篇 裡面進行介紹,在這個章節當中,我們主要還是以單純的 RPM 為主喔!

RPM 套件管理程式

RPM 的使用其實不難,只要使用 rpm 這個指令即可!鳥哥最喜歡的就是 rpm 指令的查詢功能了,可以讓我很輕易的就知道某個系統有沒有安裝鳥哥要的套件呢!此外, 我們最好還是得要知道一下,到底 RPM 類型的檔案他們是將套件的相關檔案放置在哪裡呢?還有,我們說的那個 RPM 的資料庫又是放置在哪裡呢?

RPM 預設安裝的路徑

一般來說,RPM 類型的檔案在安裝的時候,會先去讀取檔案內記載的設定參數內容,然後將該資料用來比對 Linux 系統的環境( 例如屬性相依的套件 ),例如目前 SSH 這個遠端連線軟體( 請參考伺服器篇 )使用的是 OpenSSL 的加密機制,所以,要安裝 SSH 的時候,就得要先安裝好 OpenSSL 才行啊,如果沒有安裝 OpenSSL 的話, SSH 就不讓您安裝了!這些都是 RPM 環境的要求, 如果環境相符就予以安裝,如果不符就會顯示出不符合的內容所在! 等到安裝完畢之後, rpm 就會將套件的資訊寫入:/var/lib/rpm 這個目錄中去!所以, 往後您在進行查詢的時候或者是預計要升級的時候,相關的資訊就會由 /var/lib/rpm 這個目錄的內容資料來提供囉!

一般來說,由於 RPM 有資料庫來紀錄套件相關的資訊,所以 RPM 類型的套件所擁有的檔案都放置在系統預設放置的目錄底下,亦即如同我們在 檔案屬性與目錄配置 一文當中提到的:

/etc 一些設定檔放置的目錄,例如 /etc/crontab
/usr/bin 一些可執行檔案
/usr/lib 一些程式使用的動態函式庫
/usr/share/doc 一些基本的軟體使用手冊與說明檔
/usr/share/man 一些 man page 檔案

好了,底下我們就來針對每個 RPM 的相關指令來進行說明囉!

RPM 安裝( install )

安裝就是 install 嘛!所以囉,使用 rpm 來安裝就很簡單啦!假設我要安裝一個檔名為 rp-pppoe-3.1-5.i386.rpm 的檔案,那麼我可以這樣( 記得某些套件可能需要以系統管理員的身份來安裝 ):
[root@linux ~]# rpm -i rp-pppoe-3.1-5.i386.rpm
不過,這樣的參數其實無法顯示安裝的進度,所以,通常我們會這樣下達安裝指令:
[root@linux ~]# rpm -ivh package_name
參數:
-i :install 的意思
-v :察看更細部的安裝資訊畫面
-h :以安裝資訊列顯示安裝進度
範例:

範例一:安裝 rp-pppoe-3.1-5.i386.rpm
[root@linux ~]# rpm -ivh rp-pppoe-3.1-5.i386.rpm
Preparing...     ####################################### [100%]
   1:rp-pppoe    ####################################### [100%] 

範例二、一口氣安裝兩個以上的套件時:
[root@linux ~]# rpm -ivh a.i386.rpm b.i386.rpm *.rpm
# 後面直接接上許多的套件檔案!

範例三、直接由網路上面的某個檔案安裝,以網址來安裝:
[root@linux ~]# rpm -ivh http://website.name/path/pkgname.rpm
另外,如果我們在安裝的過程當中發現問題,或者已經知道會發生的問題, 而還是『執意』要安裝這個套件時,可以使用如下的參數『強制』安裝上去:

可下達的參數代表意義
--nodeps 使用時機: 如果您在安裝某個套件時,老是發現 rpm 告訴你『有屬性相依的套件尚未安裝』, 而您又想要直接強制安裝這個套件時,可以加上 --nodeps 告知 RPM 不要去檢查套件的相依性。
危險性: 套件會有相依性的原因是因為彼此會使用到對方的機制或功能,如果強制安裝而不考慮套件的屬性相依, 則可能會造成該套件的無法正常使用!
--nomd5 使用時機: 不想檢查 RPM 檔案所含的 MD5 資訊時。
說明: 還記得我們在前一章有提到的 MD5 這個指紋辨識吧?!沒錯,這裡指的就是不要檢查 RPM 套件的 MD5 資訊。但除非您很清楚這個套件的來源,否則不建議使用這個參數。
--noscripts 使用時機: 不想讓該套件自行啟用或者自行執行某些系統指令。
說明: RPM 的優點除了可以將檔案放置到定位之外,還可以自動執行一些前置作業的指令,例如資料庫的初始化。 如果您不想要讓 RPM 幫您自動執行這一類型的指令,就加上他吧!
--replacefiles 使用時機: 如果在安裝的過程當中出現了『某個檔案已經被安裝在您的系統上面』的資訊, 又或許出現版本不合的訊息( confilcting files )時,可以使用這個參數來直接覆蓋檔案。
危險性: 覆蓋的動作是無法復原的!所以,您必須要很清楚的知道被覆蓋的檔案是真的不重要喔!否則會欲哭無淚!
--replacepkgs 使用時機: 重新安裝某個已經安裝過的套件!
--force 使用時機: 這個參數其實就是 --replacefiles 與 --replacepkgs 的綜合體!
--test 使用時機: 想要測試一下該套件是否可以被安裝到使用者的 Linux 環境當中。範例為:
rpm -ivh pkgname.i386.rpm --test

一般來說,安裝的指令大約就是這些了。通常鳥哥建議直接使用 -ivh 就好了, 如果安裝的過程中發現問題,一個一個去將問題找出來,盡量不要使用『 暴力安裝法 』,因為可能會發生很多不可預期的問題呢! 除非您很清楚的知道使用上面的參數後,安裝的結果是您預期的!

RPM 升級與更新

使用 RPM 來升級真是太簡單了!就以 -Uvh 或 -Fvh 來升級即可( 註:vh 的功能仍是在於顯示細部資訊與安裝進度而已 )!不過,這兩種升級方式是不太一樣的:

-Uvh 後面接的套件即使沒有安裝過,則系統將予以直接安裝; 若後面接的套件有安裝過舊版,則系統自動更新至新版;
-Fvh 如果後面接的套件並未安裝到您的 Linux 系統上,則該套件不會被安裝;亦即只有安裝至您 Linux 系統內的套件會被『升級』!

由上面的說明來看,如果您想要大量的升級系統舊版本的套件時( 例如剛安裝完作業系統,而想要更新套件至最新 ),使用 -Fvh 則是比較好的作法。但是需要注意的是,如果您使用的是 Fvh ,偏偏您的機器上尚無這一個套件,那麼很抱歉,該套件並不會被安裝在您的 Linux 主機上面,所以請重新以 ivh 來安裝吧!

通常有的朋友在進行整個作業系統的舊版套件修補時,喜歡這麼進行:
  1. 先到各發展商的 errata 網站或者是國內的 FTP 映像站捉下來最新的 RPM 檔案;
  2. 使用 -Fvh 來將您的系統內曾安裝過的套件進行修補與升級!(真是方便呀!)
當然囉,升級也是可以利用 --nodeps/--force 等等的參數啦!

RPM 查詢

RPM 在查詢的時候,其實查詢的地方是在 /var/lib/rpm 這個目錄下的資料庫檔案啦!另外, RPM 也可以查詢檔案內的資訊喔!那如何去查詢呢?我們底下以 簡單的範例來說明:
[root@linux ~]# rpm -qa
[root@linux ~]# rpm -q[licdR] 已安裝的套件名稱
[root@linux ~]# rpm -qf 存在於系統上面的某個檔案
[root@linux ~]# rpm -qp[licdR] 未安裝的某個檔案名稱
參數:
在查詢的部分,所有的參數之前都需要加上 -q 才是所謂的查詢!
查詢主要分為兩部分,一個是查已安裝,另一個則是查某個 rpm 檔案內容。
查詢已安裝套件的資訊:
-q  :僅查詢,後面接的套件名稱是否有安裝;
-qa :列出所有的,已經安裝在本機 Linux 系統上面的所有套件名稱;
-qi :列出該套件的詳細資訊 (information),包含開發商、版本與說明等;
-ql :列出該套件所有的檔案與目錄所在完整檔名 (list);
-qc :列出該套件的所有設定檔 (找出在 /etc/ 底下的檔名而已)
-qd :列出該套件的所有說明檔 (找出與 man 有關的檔案而已)
-qR :列出與該套件有關的相依套件所含的檔案 (Required 的意思)
-qf :由後面接的檔案名稱,找出該檔案屬於哪一個已安裝的套件;
查詢某個 RPM 檔案內含有的資訊:
-qp[icdlR]:注意 -qp 後面接的所有參數以上面的說明一致。但用途僅在於找出
	    某個 RPM 檔案內的資訊,而非已安裝的套件資訊!注意!
範例:

範例一:找出你的 Linux 是否有安裝 logrotate 這個套件?
[root@linux ~]# rpm -q logrotate
logrotate-3.7.1-10
[root@linux ~]# rpm -q logrotating
package logrotating is not installed
# 注意到,系統會去找是否有安裝後面接的套件名稱。注意,
# 不必要加上版本喔!至於顯示的結果,一看就知道有沒有安裝啦!

範例二:列出上題當中,該套件的所有目錄與檔案:
[root@linux ~]# rpm -ql logrotate
/etc/cron.daily/logrotate
/etc/logrotate.conf
......以下省略......
# 可以看出該套件到底提供了多少的檔案與目錄。

範例三:列出 logrotate 這個套件的相關說明資料:
[root@linux ~]# rpm -qi logrotate
Name        : logrotate                Relocations: (not relocatable)
Version     : 3.7.1                         Vendor: Red Hat, Inc.
Release     : 10                        Build Date: Fri Apr  1 03:54:42 2005
Install Date: Sat Jun 25 08:28:26 2005  Build Host: tweety.build.redhat.com
Group       : 系統環境/基礎             Source RPM: logrotate-3.7.1-10.src.rpm
Size        : 47825                        License: GPL
Signature   : DSA/SHA1, Sat May 21 01:34:11 2005, Key ID b44269d04f2a6fd2
Packager    : Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla>
Summary     : 循環、壓縮、移除以及郵寄系統紀錄檔案。
Description :
The logrotate utility is designed to simplify the administration of
log files on a system which generates a lot of log files. Logrotate
allows for the automatic rotation, compression, removal, and mailing of
log files. Logrotate can be set to handle a log file daily, weekly,
monthly, or when the log file gets to a certain size. Normally,
logrotate runs as a daily cron job.
# 列出該套件的 information (資訊),裡面的資訊可多著呢,包括了套件名稱、
# 版本、開發商、SRPM檔案名稱、打包次數、簡單說明資訊、套件打包者、
# 安裝日期等等!如果想要詳細的知道該套件的資料,用這個參數來瞭解一下

範例四:分別僅找出 logrotate 的設定檔與說明檔
[root@linux ~]# rpm -qc logrotate
[root@linux ~]# rpm -qd logrotate

範例五:若要成功安裝 logrotate ,他還需要什麼檔案的幫忙?
[root@linux ~]# rpm -qR logrotate
/bin/sh
config(logrotate) = 3.7.1-10
libc.so.6
....以下省略....
# 由這裡看起來,呵呵~還需要很多檔案的支援才行喔!

範例六:由上面的範例五,找出 /bin/sh 是那個套件提供的?
[root@linux ~]# rpm -qf /bin/sh
bash-3.0-31
# 這個參數後面接的可是『檔案』吶!不像前面都是接套件喔!
# 這個功能在查詢系統的某個檔案屬於哪一個套件所有的。

範例七:假設我有下載一個 RPM 檔案,想要知道該檔案的需求檔案,該如何?
[root@linux ~]# rpm -qpR filename.i386.rpm
# 加上 -qpR ,找出該檔案需求的資料!
常見的查詢就是這些了!要特別說明的是,在查詢本機上面的 RPM 套件相關資訊時, 不需要加上版本的名稱,只要加上套件名稱即可!因為他會由 /var/lib/rpm 這個資料庫裡面去查詢, 所以我們可以不需要加上版本名稱。但是查詢某個 RPM 檔案就不同了, 我們必須要列出整個檔案的完整檔名才行~ 這一點朋友們常常會搞錯。底下我們就來做幾個簡單的練習吧!

例題:
我想要知道我的系統當中,以 c 開頭的套件有幾個,如何實做?
    rpm -qa | grep ^c | wc -l
我的 WWW 伺服器為 Apache ,我知道他使用的 RPM 套件檔名為 httpd 。 現在,我想要知道這個套件的所有設定檔放置在何處,可以怎麼作?
    rpm -qc httpd
承上題,如果查出來的設定檔案已經被我改過,但是我忘記了曾經修改過哪些地方, 所以想要直接重新安裝一次該套件,該如何作?
    假設該套件在網路上的網址為:
    http://web.site.name/path/httpd-x.x.xx.i386.rpm
    則我可以這樣做:
    rpm -ivh http://web.site.name/path/httpd-x.x.xx.i386.rpm --replacepkgs
如果我誤砍了某個重要檔案,例如 /etc/crontab,偏偏不曉得他屬於哪一個套件,該怎麼辦?!
    雖然已經沒有這個檔案了,不過沒有關係,因為 RPM 有紀錄在 /var/lib/rpm 當中的資料庫啊!所以直接下達:
    rpm -qf /etc/crontab
    就可以知道是那個套件囉!重新安裝一次該套件即可!

RPM 驗證與數位簽章

驗證的功能主要在於提供系統管理員一個有用的管理機制!作用的方式是『 使用 /var/lib/rpm 底下的資料庫內容來比對目前 Linux 系統的環境下的所有套件檔案 』也就是說,當您有資料不小心遺失, 或者是因為您誤殺了某個套件的檔案,或者是不小心不知道修改到某一個套件的檔案內容, 就用這個簡單的方法來驗證一下原本的檔案系統吧! 好讓您瞭解這一陣子到底是修改到哪些檔案資料了!驗證的方式很簡單:
[root@linux ~]# rpm -Va
[root@linux ~]# rpm -V  已安裝的套件名稱
[root@linux ~]# rpm -Vp 某個 RPM 檔案的檔名
[root@linux ~]# rpm -Vf 在系統上面的某個檔案
參數:
-V  :後面加的是套件名稱,若該套件所含的檔案被更動過,才會列出來;
-Va :列出目前系統上面所有可能被更動過的檔案;
-Vp :後面加的是檔案名稱,列出該套件內可能被更動過的檔案;
-Vf :列出某個檔案是否被更動過~
範例:

範例一:列出你的 Linux 內的 logrotate 這個套件是否被更動過?
[root@linux ~]# rpm -V logrotate
# 如果沒有出現任何訊息,恭喜你,該套件沒有被更動過。
# 如果有出現任何訊息,才是有出現狀況啊!

範例二:查詢一下,你的 /etc/crontab 是否有被更動過?
[root@linux ~]# rpm -Vf /etc/crontab
S.5....T  c /etc/crontab
# 瞧!因為有被更動過,所以會列出被更動過的資訊!
好了,那麼我怎麼知道到底我的檔案被更動過的內容是什麼?呵呵!簡單的說明一下吧! 例如,我們檢查一下 logrotate 這個套件:
[root@linux ~]# rpm -ql logrotate
/etc/cron.daily/logrotate
/etc/logrotate.conf
/etc/logrotate.d
/usr/sbin/logrotate
/usr/share/doc/logrotate-3.7.1
/usr/share/doc/logrotate-3.7.1/CHANGES
/usr/share/man/man8/logrotate.8.gz
/var/lib/logrotate.status
# 呵呵!共有八個檔案啊! 

[root@linux ~]# rpm -V logrotate
..5....T c /etc/logrotate.conf
# 上面的資訊是這樣的:
S :file Size differs
    檔案的容量大小是否被改變
M :Mode differs (includes permissions and file type)
    檔案的類型或檔案的屬性,如是否可執行等參數已被改變
5 :MD5 sum differs
    MD5 這一種加密防駭的屬性已被改變
D :Device major/minor number mis-match
    裝置名稱已被改變
L :readLink(2) path mis-match
    Link 屬性已被改變
U :User ownership differs
    檔案的所屬人已被改變
G :Group ownership differs
    檔案的所屬群組已被改變
T :mTime differs
    檔案的建立時間已被改變
所以,如果當一個檔案所有的資訊都被更動過,那麼他的顯示就會是:
SM5DLUGT c filename
至於那個 c 代表的是『 Config file 』的意思,也就是檔案的類型,檔案類型有底下這幾類:
  • c :設定檔(config file)
  • d :文件資料檔(documentation)
  • g :鬼檔案~通常是該檔案不被某個套件所包含,較少發生!(ghost file)
  • l :授權檔案(license file)
  • r :讀我檔案(read me)
經過驗證的功能,您就可以知道那個檔案被更動過。那麼如果該檔案的變更是『預期中的』, 那麼就沒有什麼大問題,但是如果該檔案是『非預期的』,那麼是否被入侵了呢?呵呵! 得注意注意囉!

再來,由於數位簽證的盛行,我們 Linux 的 RPM 也可以利用數位簽證來判斷待安裝的套件檔案是否有問題喔!一般我們使用的是 GPG 的金鑰( public key )。應用的方法很簡單,首先, 當我們想要使用某個團體釋出的套件時,就需要將他們釋出的 GPG 金鑰先安裝在自己的 Linux 系統上。然後,當安裝該團體釋出的套件時,就會檢查兩者的 key 是否相同,如果相同就直接安裝,如果不同就會在螢幕上面顯示訊息告知您並未安裝該團體的 GPG 金鑰!

安裝金鑰的方法很簡單,例如 Red Hat 本身就有金鑰在系統當中,安裝如下:
[root@linux ~]# rpm --import /usr/share/rhn/RPM-GPG-KEY
一般來說,您的 Linux distributions 都會釋出自己的 GPG Key 的,如果是 Red Hat 系統的話, 可以使用:
[root@linux ~]# locate GPG-KEY
來進行搜尋檔案的工作,至於這些金鑰的內容,我們可以這樣查詢喔:
[root@linux ~]# rpm -qa | grep gpg
libgpg-error-1.0-2
gpg-pubkey-4f2a6fd2-3f9d9d3b
[root@linux ~]# rpm -qi gpg-pubkey-4f2a6fd2-3f9d9d3b
Name        : gpg-pubkey               Relocations: (not relocatable)
Version     : 4f2a6fd2                      Vendor: (none)
Release     : 3f9d9d3b                  Build Date: Sat Jun 25 22:13:00 2005
Install Date: Sat Jun 25 22:13:00 2005  Build Host: localhost
Group       : Public Keys               Source RPM: (none)
Size        : 0                            License: pubkey
Signature   : (none)
Summary     : gpg(Fedora Project <fedora@redhat.com>)
Description :
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: rpm-4.4.1 (beecrypt-3.0.0)

mQGiBD+dnTsRBACwnlz4AhctOLlVBAsq+RaU82nb5P3bD1YJJpsAce1Ckd2sBUOJD11NUCqH
.....中間省略.....
=mJAx
-----END PGP PUBLIC KEY BLOCK-----
這樣就能看到相關的資訊囉! ^_^

RPM 反安裝與重建資料庫

反安裝就是將套件解除安裝啦!要注意的是,『解安裝的過程一定要由最上層往下解除』,以 rp-pppoe 為例,這一個套件主要是依據 ppp 這個套件來安裝的,所以當您要解除 ppp 的時候,就必須要先解除 rp-pppoe 才行!否則就會發生結構上的問題啦!這個可以由建築物來說明, 如果你要拆除五、六樓,那麼當然要由六樓拆起,否則拆了第五樓,那麼上面的樓層難道會懸空?

那麼重建資料庫呢?由於我們會一直在修改一些檔案內容,例如 /etc/xinetd.d 裡頭的參數檔案,加上可能自系統操作的過程中新增、移除等等的動作,導致系統的資料庫有點亂, 這個時候可以使用--rebuilddb 來重建一下 rpm 的資料庫!這兩個方法的參數如下囉:
[root@linux ~]# rpm -e logrotate  <==解安裝 logrotate 套件
[root@linux ~]# rpm --rebuilddb   <==重建資料庫

SRPM 的使用

談完了 RPM 類型的套件之後,再來我們談一談包含了 Source code 的 SRPM 該如何使用呢?!假如今天我們由網路上面下載了一個 SRPM 的檔案,該如何安裝他?又,如果我想要修改這個 SRPM 裡面原始碼的相關設定值,又該如何訂正與重新編譯呢?!此外,最需要注意的是,新版的 rpm 已經將 RPM 與 SRPM 的指令分開了,SRPM 使用的是 rpmbuild 這個指令,而不是 rpm 喔!如果您是 Red Hat 7.3 以前的用戶,那麼請使用 rpm 來替代 rpmbuild 啦!

利用系統預設值安裝 SRPM 檔案

假設我下載了一個 SRPM 的檔案,又不想要修訂這個檔案內的原始碼與相關的設定值, 那麼我可以直接編譯並安裝嗎?當然可以!利用 rpmbuild 配合參數即可。參數主要有底下兩個:

--rebuild 這個參數會將後面的 SRPM 進行『編譯』與『打包』的動作,最後會產生 RPM 的檔案,但是產生的 RPM 檔案並沒有安裝到系統上。當您使用 --rebuild 的時候,最後通常會發現一行字體:
Wrote: /usr/src/RPM/RPMS/i386/pkgname.i386.rpm
這個就是編譯完成的 RPM 檔案囉!那麼這個檔案就可以用來安裝啦!安裝的時候請加絕對路徑來安裝即可!
--recompile 這個動作會直接的『編譯』『打包』並且『安裝』囉!請注意, rebuild 僅『編譯並打包』而已,而 recompile 不但進行編譯跟打包,還同時進行『安裝』了!

一般來說,如果編譯的動作順利的話,那麼編譯過程所產生的中間暫存檔都會被自動刪除, 如果發生任何錯誤,則該中間檔案會被保留在系統上,等待使用者的除錯動作!那麼, 該如何除錯呢?!如果想要自行除錯,就得要知道利用 SRPM 的時候,系統會動用到哪些重要的目錄了!底下我們就來談一談當處理 SRPM 時,系統會使用到的目錄。

SRPM 使用的路徑與需要的套件

SRPM 既然含有 source code ,那麼其中必定有設定檔囉,所以首先我們必需要知道,這個 SRPM 在進行編譯的時候,會使用到哪些目錄呢?這樣一來才能夠來修改嘛!你可以到你的 /usr/src 這個目錄裡面去查看一下,通常每個 distribution 提供的目錄都不太相同,以 FC4 為例,他是以 /usr/src/redhat/ 為工作目錄, Openlinux 則是以 /usr/src/openlinux 為工作目錄!無論如何,反正就是在 /usr/src 這個目錄下就對了!好了到 /usr/src/redhat 裡頭去看一看呦:

/usr/src/redhat/SPEC 這個目錄當中放置的是該套件的設定檔,例如這個套件的資訊參數、設定項目等等都放置在這裡;
/usr/src/redhat/SOURCE 這個目錄當中放置的是該套件的原始檔(*.tar.gz的檔案)以及 config 這個設定檔;
/usr/src/redhat/BUILD 在編譯的過程中,有些暫存的資料都會放置在這個目錄當中;
/usr/src/redhat/RPMS 經過編譯之後,並且順利的編譯成功之後,將打包完成的檔案放置在這個目錄當中。裡頭有包含了 i386, i586, i686, noarch.... 等等的次目錄。

此外,在編譯的過程當中,可能會發生不明的錯誤,或者是設定的錯誤,這個時候就會在 /tmp 底下產生一個相對應的錯誤檔,您可以根據該錯誤檔進行除錯的工作呢! 等到所有的問題都解決之後,也編譯成功了,那麼剛剛解壓縮之後的檔案,就是在 /usr/src/redhat/SPEC, SOURCE, BUILD 等等的檔案都會被殺掉,而只剩下放置在 /usr/src/redhat/RPMS 底下的檔案了!

由於 SRPM 需要重新編譯,而編譯的過程當中,我們至少需要有 make 與其相關的程式,及 gcc, c, c++ 等其他的編譯用的程式語言來進行編譯,所以, 如果您在安裝的過程當中沒有選取軟體開發工具之類的套件,呵呵!得重新拿出你的光碟, 然後再安裝喔!哈哈!只是得要克服一大堆的屬性相依的問題就是了~ 嗯!還是建議您再次的看一下如何安裝吧!

設定檔的主要內容

剛剛我們在上面提過了,SRPM 還可以更改一些設定的內容,那麼要如何修改這些設定的內容呢?我們以簡單的 rp-pppoe 這個套件來說明好了。比較可惜的是, rp-pppoe 的官方網站目前 (2005/10) 似乎不再提供新的 SRPM 檔案了,所以,我們是由 rpmfind.net ( http://rpmfind.net/ ) 找到給 FC4 使用的 SRPM 檔案 (是測試版喔!) , 你可以自行查閱一下這個 rp-pppoe 相關的資訊以及 rpmfind.net 網站提供的資訊。 至於基本的過程如下:(鳥哥在這裡假設你已經將 rp-pppoe-3.5-30.src.rpm 下載到 /root 底下了)
[root@linux ~]# rpm -i /root/rp-pppoe-3.5-30.src.rpm
# 這個過程不會顯示任何東西,他只會將 SRPM 的檔案解開後,放置到 
# /usr/src/redhat 下!

[root@linux ~]# find /usr/src/redhat/ -type f
/usr/src/redhat/SOURCES/rp-pppoe-3.5-buildroot.patch
/usr/src/redhat/SOURCES/adsl-stop
/usr/src/redhat/SOURCES/adsl-start
/usr/src/redhat/SOURCES/adsl-setup
/usr/src/redhat/SOURCES/rp-pppoe-3.4-redhat.patch
/usr/src/redhat/SOURCES/adsl-status
/usr/src/redhat/SOURCES/rp-pppoe-3.5-firewall.patch
/usr/src/redhat/SOURCES/adsl-connect
/usr/src/redhat/SOURCES/rp-pppoe-3.5.tar.gz
/usr/src/redhat/SPECS/rp-pppoe.spec
# 主要含有原始碼與一個重要的設定檔啊! rp-pppoe.spec !
好了,來看看我們的設定參數檔,亦即是在 /usr/src/redhat/SPECS 內的 *.spec 檔案囉!
[root@linux ~]# cd /usr/src/redhat/SPECS
[root@linux SPECS]# vi rp-pppoe.spec
# 1. 首先,這個部分在介紹整個套件的基本相關資訊!不論是版本還是釋出次數等。
Summary: A PPP over Ethernet client (for xDSL support).
Name: rp-pppoe
Version: 3.5
Release: 30
License: GPL
Group: System Environment/Daemons
Url: http://www.roaringpenguin.com/pppoe/
Source: http://www.roaringpenguin.com/rp-pppoe-%{version}.tar.gz
Source1: adsl-connect
Source2: adsl-setup
.....中間省略.....

# 2. 這部分則是在設定相依屬性需求的地方!
Prereq: /sbin/chkconfig
Prereq: /sbin/service
Prereq: fileutils
Requires: ppp >= 2.4.2
Requires: initscripts >= 5.92
Requires: iproute >= 2.6
ExcludeArch: s390 s390x

%description
PPPoE (Point-to-Point Protocol over Ethernet) is a protocol used by
many ADSL Internet Service Providers. This package contains the
Roaring Penguin PPPoE client, a user-mode program that does not
require any kernel modifications. It is fully compliant with RFC 2516,
the official PPPoE specification.

# 3. 編譯前的預處理,以及編譯過程當中所需要進行的指令,都寫在這裡
#    尤其 %build 底下的資料,幾乎就是 makefile 裡面的資訊啊!
%prep
%setup -q
%patch0 -p1 -b .config
%patch1 -p1 -b .buildroot
%patch2 -p1 -b .ipchains

%build
cd src
autoconf
CFLAGS="-D_GNU_SOURCE" %configure
make

install -m 0755 %{SOURCE1} scripts
install -m 0755 %{SOURCE2} scripts
install -m 0755 %{SOURCE3} scripts
install -m 0755 %{SOURCE4} scripts
install -m 0755 %{SOURCE5} scripts

%install
rm -rf $RPM_BUILD_ROOT
.....中間省略.....

# 4. 這裡列出,這個套件釋出的檔案有哪些的意思!
%files
%defattr(-,root,root)
%doc doc/LICENSE scripts/adsl-connect scripts/adsl-setup scripts/adsl-init
%doc scripts/adsl-start scripts/adsl-status scripts/adsl-stop
%doc configs
%config(noreplace) %{_sysconfdir}/ppp/pppoe-server-options
%config(noreplace) %{_sysconfdir}/ppp/firewall*
/sbin/*
%{_sbindir}/*
%{_mandir}/man?/*

# 5. 列出這個套件的更改歷史紀錄檔!
%changelog
* Mon Aug 15 2005 Than Ngo <than@redhat.com> 3.5-30
- defaultroute should not overridden #152014
.....中間省略.....
* Wed May 31 2000 Than Ngo <than@redhat.de>
- adopted for Winston.
注意到的是rp-pppoe.sepc這個檔案,這是主要的將SRPM編譯成RPM的設定檔,他的基本規則可以這樣看:
  1. 整個檔案的開頭以Summary為開始,這部份的設定都是最基礎的說明內容;
  2. 然後每個不同的段落之間,都以%來做為開頭,例如%prep與%install等;
我們來談一談幾個常見的SRPM設定段落:

  • 系統整體資訊方面:
  • Summary 主要的套件說明,例如上表中,我們說明了他是 ppp 的撥接用途啦!
    Name 這個就是套件的名稱;
    Version 這個是套件的版本資訊;
    Release 這個是該版本打包的次數說明;
    License 這個套件的授權模式,我們是使用 GPL 啦!
    Group 這個套件的發展團體名稱;
    Source 這個套件的來源,如果是網路上下載的套件,通常一定會有這個資訊來告訴大家這個原始檔的來源!
    Url 這個原始碼的主要官方網站;
    Packager 這個套件是經由誰來打包的呢?
    Vender 發展的廠商哪;
    ExclusiveArch 這個是說明這個套件的適合安裝的硬體,通常預設為 i386,當然,你也可以調整為 i586 啦等等的!
    Requires 如果你這個套件還需要其他的套件的支援,那麼這裡就必需寫上來,則當你製作成 RPM 之後,系統就會自動的去檢查啦!這就是『相依屬性』的主要來源囉!

    上面幾個資料通常都必需要寫啦!但是如果你的軟體沒有相依屬性的關係時, 那麼就可以不需要那個Requires囉!
  • %description
  • 將您的套件做一個簡短的說明!這個也是必需要的。
  • %prep
  • 這部份的設定在於『尚未進行設定或安裝之前,你要編譯完成的 RPM 幫你事先做的事情』,就是 prepare 的簡寫囉!那麼他的工作事項主要有:
    1. 尋找套件所需要的目錄是否已經存在?確認用的!
    2. 事先建立您的套件所需要的目錄,或者事先需要進行的任務;
    3. 如果待安裝的Linux系統內已經有安裝的時候可能會被覆蓋掉的檔案時, 那麼就必需要進行備份(backup)的工作了!
    大致的工作就是這些啦!
  • %setup
  • 這個段落就是在建立我們在 Tarball 當中說明的那個 Makefile 檔案啦!所以呢,當然就是執行 ./config 之類的設定檔案囉! 那麼如果你要自己新增自己的參數,就可以在這個地方加入你的設定值! 如果你的軟體本身沒有這方面的需要,裡面就不需要編寫內容囉!
  • %build
  • build 就是建立啊!所以當然囉,這個段落就是在談怎麼 make 編譯成為可執行的程式囉!
  • %install
  • 編譯完成 (build) 之後,就是要安裝啦!安裝就是寫在這裡,也就是類似 Tarball 裡面的 make install的意思囉!
  • %files
  • 這個套件安裝的檔案都需要寫到這裡來,當然包括了『目錄』喔! 所以連同目錄請一起寫到這個段落當中!以備查驗呢!^_^
  • %changelog
  • 這個主要則是在記錄這個套件曾經的更新紀錄囉!
    好了,那麼如果您有自訂的資訊想要加入的話,就選擇你要加入的那個段落,將他修改一下吧! 例如,如果你在設定 Makefile 的時候,希望能夠多一些額外的參數設定,那麼就找到 %setup 或 %build 那個段落,將他修改成您所需要的樣子,就可以囉!

    SRPM 的編譯指令

    再來呢?嗯!沒錯,修改完成了,自然就是要將他編譯成可以安裝的 RPM 檔案啦! 這個時候我們就可以直接在 /usr/src/redhat/SPECS 底下下達:
    [root@linux ~]# rpmbuild -bb rp-pppoe.spec  <==編譯成RPM檔案
    [root@linux ~]# rpmbuild -ba rp-pppoe.spec  <==打包成SRPM檔案
    
    這個時候系統就會這樣做:
    1. 先進入到 BUILD 這個目錄中,在 Fedora 底下就是 /usr/src/redhat/BUILD 這個目錄;
    2. 依照 *.spec 檔案內的 Name 與 Version 設定定義出工作的目錄名稱, 以我們上面的例子為例,那麼系統就會在 BUILD 目錄中先刪除 rp-pppoe-3.5 的目錄,再重新建立一個 rp-pppoe-3.5 的目錄,並進入該目錄;
    3. 在新建的目錄裡面,針對 SOURCES 目錄下的來源檔案,也就是 *.spec 裡面的 Source 設定的那個檔案,以 tar 進行解壓縮,以我們這個例子來說,則會在 /usr/src/redhat/BUILD/rp-pppoe-3.5 當中,將 /usr/src/redhat/SOURCES/rp-pppoe-3.5.tar.gz 進行解壓縮啦!
    4. 然後就開始 %setup 的工作;
    5. 再來開始 %build 及 %install 的設定與編譯!
    6. 最後將完成打包的檔案給他放置到該放置的地方去,如果你的規定的硬體是在i386的系統,那麼最後編譯成功的*.i386.rpm檔案就會被放置在/usr/src/RPM/RPMS/i386裡面囉!如果是i586那麼自然就是 /usr/src/redhat/RPMS/i586目錄下囉!
    整個步驟大概就是這樣子!最後的結果資料會放置在RPMS那個目錄底下就對啦!

    一個打包自己套件的範例

    這個就有趣了!我們自己來編輯一下自己製作的 RPM 怎麼樣?會很難嗎?完全不會! 這裡簡單的以一個小例子來說明喔!請注意,這個真的只是一個小例子,所以不要覺得奇怪喔! 其中,比較需要注意的,由於在上面的步驟說明中,我們知道在將 SRPM 編譯成為RPM的時候,會以 tar 這支程式來將檔案解開,因此,我們在進行來源檔案的建立時, 就必需要將他打包成為一個 tar.gz 的 tarball 的檔案才行

    假設我們編輯了一支script,內容是這樣:
    [root@linux ~]# cd /usr/src/redhat/SOURCES
    [root@linux SOURCES]# vi showvbird.sh
    #!/bin/bash
    # This file is just used to demo the RPM packaging.
    # the only thing is showing the hostname.
    HOST=`/bin/hostname`
    /bin/echo $HOST
    # 先隨便建立一個 shell script ,這個是自己的套件的意思啦!
    
    [root@linux SOURCES]# chmod 755 showvbird.sh
    [root@linux SOURCES]# tar -zcvf showvbird.tar.gz showvbird.sh
    # 注意喔!務必打包才行啊!
    
    上面的動作中,我們編輯了一個 shell script 檔案,檔名為 showvbird.sh,並且將他打包成為具有 gzip 壓縮的 tarball 檔案,也就是 showvbird.tar.gz 這樣的檔案才行!請注意,這個 showvbird.tar.gz 檔案『必需』放置在 SOURCES 目錄之下!

    再來則是要編輯那個很重要的 *.spec 檔案囉!你可以這樣簡單的編寫一下:
    [root@linux SOURCE]# cd /usr/src/redhat/SPECS
    [root@linux SPECS]# vi showvbird.spec
    Summary:   This is a demo RPM package.
    Name:      showvbird
    Version:   1.0
    Release:   1
    License:   GPL
    Group:     VBird's Home
    Source:    showvbird.tar.gz   <==記得喔!這裡寫的是剛剛建立的 tarball
    Url:       http://linux.vbird.org
    Packager:  VBird
    
    %description
    This package is just a demo RPM.
    
    %prep
    %setup -c
    %install
    install -m 755 showvbird.sh /usr/local/bin/showvbird.sh
    
    %files
    /usr/local/bin/showvbird.sh
    
    好了!開始給他編譯並打包成為 RPM 檔案啦!
    [root@linux SPECS]# rpmbuild -bb showvbird.spec
    .....中間省略......
    Requires: /bin/bash
    Checking for unpackaged file(s): /usr/lib/rpm/check-files %{buildroot}
    Wrote: /usr/src/redhat/RPMS/i386/showvbird-1.0-1.i386.rpm
    
    最後這個被打包成功的檔案就被放置在 /usr/src/redhat/RPMS/i386/showvbird-1.0-1.i386.rpm 囉!然後給他安裝一下:
    [root@linux SPECS]# rpm -ivh ../RPMS/i386/showvbird-1.0-1.i386.rpm
    Preparing...                ########################################### [100%]
       1:showvbird              ########################################### [100%]
    
    [root@linux SPECS]# rpm -qi showvbird
    Name        : showvbird                Relocations: (not relocatable)
    Version     : 1.0                           Vendor: (none)
    Release     : 1                         Build Date: Mon Oct  3 11:08:30 2005
    Install Date: Mon Oct  3 11:11:30 2005  Build Host: linux.site.tw
    Group       : VBird's Home              Source RPM: showvbird-1.0-1.src.rpm
    Size        : 143                          License: GPL
    Signature   : (none)
    Packager    : VBird
    URL         : http://linux.vbird.org
    Summary     : This is a demo RPM package.
    Description :
    This package is just a demo RPM.
    
    [root@linux SPECS]# which showvbird.sh
    /usr/local/bin/showvbird.sh
    [root@linux SPECS]# rpm -ql showvbird
    /usr/local/bin/showvbird.sh  <==果然記錄起來了!自己的軟體呢!
    
    用很簡單的方式,就可以將自己的軟體或者程式給他修改與設定妥當!很不錯吧! 以後您就可以自行設定你的 RPM 囉!當然,也可以手動修改您的 SRPM 的來源檔內容囉!

    要選擇 RPM 還是 Tarball?

  • 優先選擇 RPM:
  • 這一直是個有趣的問題:『如果我要升級的話,或者是全新安裝一個新的套件, 那麼該選擇 RPM 還是 Tarball 來安裝呢?』!基本上,如果有 RPM 可以提供給您的 distribution 來安裝,並且沒有嚴重的相依屬性的問題時,呵呵!選擇 RPM 來安裝會是一個比較好的解決方案, Why ?這是由於剛剛上面就提到的 RPM 的好處 啦!可以具有檔案與資料均有紀錄的優點,這就是上面提到的 /var/lib/rpm 這個目錄裡面的資料庫,這個記錄可以讓你在管理上更為便利,包括上面提到的 RPM 的升級、安裝、驗證與移除等等。尤其是在查詢上面!可以讓你在管理你的系統上面更為便利。

    但是 RPM 也不是沒有缺點的,包括最為大家所抱怨連連的『 屬性相依 』的問題,每一個不同版本之間,就必須要以不同的 RPM 檔案來安裝!此外,如果要升級『某一個套件』而已時, 通常還需要連帶其他的套件也必須要一起升級才行,否則會有問題!此外,當一個套件經過了『 大幅度的修改 』之後,通常舊的 RPM 與新的 RPM 之間已經幾乎無法『完全相容』時, 呵呵!那麼升級或者是移除的手續可是會累壞人的!

    例如前兩年朋友們常常問到的 Apache 1.3.xx 與 2.0.xx 的版本升級問題! 由於這兩個版本之間的架構差異性太大,加上版本屬性相依問題,所以很難得到一個完滿的解決方案,這個時候 RPM 就不那麼合適了。( 除非您要一個一個的將 Apache 移除,連同其相依的套件,然後再將 Apache 一個一個的安裝,包括新套件的相依套件! ^_^ .....鳥哥是不會這麼做的啦! )

  • 簡易方法:
  • 如果 RPM 檔案並不是這麼容易取得的話,這個時候 Tarball 的方式就特別適合您的安裝了!這是因為 Tarball 可以自行設定編譯時的參數,此外,也可以自行設定『安裝路徑』, 相當的適合於想要安裝『多個不同版本的同一個套件』的情況( 說穿了就是測試機器 )!

    這是怎麼說呢?!由於 RPM 必須要配合系統裡面其他的相依屬性的套件,所以基本上, 他的安裝路徑( 就是每個檔案的放置路徑 )理論上是必須要放在固定的目錄的,就是不能隨意的改變他的安裝路徑。 因此,當有兩個不同版本的相同套件想要測試的時候,大概一定就得將原先的版本移除之後, 才能安裝使用新的版本囉!(此外,由於相依的套件幾乎都已經包含在 tarball 當中了,所以安裝上面其實並不難啦!)

    相對於 RPM 的制式格式, tarball 可就靈活多了!你可以自行編譯套件並且將他安裝在不同的路徑, 只要在啟動的時候選擇正確的版本,那麼不同版本的套件可以同時的存在於一個系統當中, 而且可以透過選擇啟動的檔案來啟動不同的版本。當然囉!你也可以讓 tarball 的安裝與 RPM 的安裝同時存在於一個系統當中,但是需要特別留意的是, 你在啟動該套件的時候,千萬記得你的啟動路徑!免得啟動到了錯誤的版本了!呵呵!( 這也是一個系統存在不同多個版本的套件容易發生的錯誤! 希望大家都能夠瞭解這個問題呢! )

    所以說,為了避免這種路徑上的錯誤困擾,基本上,我們都希望 Tarball 的安裝路徑可以設定在 Linux 原本就規劃要給大家安裝的路徑『 /usr/local 』這個路徑下!這樣可以省去相當多尋找檔案的時間! 而且在管理上面也會比較容易!呵呵!

    不過, Tarball 最麻煩的地方有幾點:
    • 反安裝:
      Tarball 最麻煩的地方就在於他的『解安裝』了! 相當的討厭!如果是簡單的直接將所有的套件安裝在一個目錄下的話,例如 /usr/local/mrtg 時,那麼解安裝還算簡單,就是將該路徑殺掉就 OK 啦!但是如果是類似 sendmail 這一種呢?他的路徑都是已經放置死的( 需要在 /etc/sendmail.cf、/etc/mail 底下 )那麼追蹤反安裝的路徑就很煩人;

    • 線上查詢:
      如果您的安裝路徑是在 /usr/local 底下的話,那麼執行檔會被放置到 /usr/local/bin ,或者是 /usr/local/sbin 底下,參數檔會放在 /usr/local/etc 底下,線上查詢檔案會放在 /usr/local/man 底下,所以在設定上面還有查詢上面還算簡單( 路徑設定一下即可! ),不過,如果你是將套件安裝在單獨的路徑下呢?例如 /usr/local/mrtg 底下,那麼執行檔變成了 /usr/local/mrtg/bin 底下,最麻煩的地方就是 man page ( 線上查詢 )放置的地點會變成在 /usr/local/mrtg/man 底下了!糟糕!那麼預設的 man page 路徑就找不到該說明檔囉! 這個時候就必須要手動的將該路徑加入 /etc/man.conf 這個檔案中!而且執行檔放置的路徑也沒有指定,可以經由 (1)Link 的方式或者 (2)設定 PATH 環境變數的方式將該路徑加進去啦!確實是比較麻煩的啦!
    所以說,RPM 與 Tarball 各有其優缺點,不過,如果有 RPM 的話,那麼優先權還是在於 RPM 安裝上面,畢竟管理上比較便利,但是如果套件的架構差異性太大, 或者是無法解決相依屬性的問題,那麼與其花大把的時間與精力在解決屬性相依的問題上,還不如直接以 tarball 來安裝,輕鬆又愜意!

    重點回顧

    • RPM 的全名是 Red Hat Package Manager,原本是由 Red Hat 公司所發展的,流傳甚廣;
    • RPM 類型的套件中,所含有的套件是經過編譯後的 binary file ,所以可以直接安裝在使用者端( Client )的系統上,不過,也由於如此,所以 RPM 對於安裝者的環境要求相當嚴格;
    • RPM 除了將套件安裝至使用者的系統上之外,還會將該套件的版本、名稱、檔案與目錄配置、系統需求等等均記錄於資料庫( /var/lib/rpm )當中,方便未來的查詢與升級、移除;
    • RPM 可針對不同的硬體等級來加以編譯,製作出來的檔案可於副檔名( i386, i586, i686 )來分辨;
    • RPM 最大的問題為套件之間的相依性問題;
    • SRPM 為 Source RPM ,內含的檔案為 Source code 而非為 binary file ,所以安裝 SRPM 時還需要經過 compile ,不過,SRPM 最大的優點就是可以讓使用者自行修改設定參數( makefile/configure 的參數 ),以符合使用者自己的 Linux 環境;

    參考資源

    剛剛最前面說過了,套件升級最主要的考量就是『安全性』啦!所以請隨時注意安全性方面的問題! 目前國內的主要安全網站為:『台灣網路危機處理小組』這個組織,請隨時注意上面發佈的新聞!另外, 如果跟鳥哥一樣使用的是 Red Hat 的 distrubution 的話,那麼 Red Hat 的 Errata 網頁則不可不光臨!好啦!底下列出幾個 RPM 相關的網頁與 Red Hat 的 Errata 網頁提供大家參考囉!

    課後練習

    • 簡單說明 RPM 與 SRPM 的異同?
    • RPM 檔案是由程式打包者 (通常是由 distribution 的開發商) 藉由程式的原始碼,在特定的平台上面所編譯成功的 binary program 的資料,並將該資料製作成為 RPM 的格式,以方便相同軟、硬體平台的使用者之安裝使用。 在安裝時顯的很簡單,因為程式打包者的平台與使用者所使用的平台預設為相同。
      至於 SRPM 則是藉由與 RPM 相同的設定檔資料,不過將原始碼直接包在 SRPM 檔案當中,而不經過編譯。 因為 SRPM 所內含的資料為原始碼,所以安裝時必須要再經過編譯的行為才能成為 RPM 並提供使用者安裝。
    • 查詢系統上的 RPM 套件資料時,系統由何處取得該套件的訊息?
    • 在 /var/lib/rpm/* 當中的資料庫檔案所取得。
    • 假設我想要安裝一個套件,例如 pkgname.i386.rpm ,但卻老是發生無法安裝的問題,請問我可以加入哪些參數來強制安裝他?
    • 可以加入 --nodeps 等參數。例如 rpm -ivh --nodeps pkgname.i386.rpm
    • 承上題,您認為強制安裝之後,該套件是否可以正常執行?為什麼?
    • 一般來說,應該是『不能執行』的,因為該軟體具有相依屬性的問題, 某些時刻該軟體的程式可能需要呼叫外部的函式庫,但函式庫可能未安裝,因此當然無法執行成功。
    • 有些人使用 OpenLinux 3.1 Server 安裝在自己的 P-166 MMX ,卻發現無法安裝, 在查詢了該原版光碟的內容,發現裡面的檔案名稱為 ***.i686.rpm 。請問,無法安裝的可能原因為何?
    • 因為 P-166MMX 為 i586 的硬體平台,而 OpenLinux 為針對 i686 的硬體平台進行最佳化, 因此很可能由於下達的參數無法支援的問題,導致無法安裝成功。
    • 請問我使用 rpm -Fvh *.rpm 及 rpm -Uvh *.rpm 來升級時,兩者有何不同?
    • -Uvh 後面接的軟體,如果原本未安裝,則直接安裝,原本已安裝時,則直接升級;
      -Fvh 後面接的軟體,如果原本未安裝,則不安裝,原本已安裝時,則直接升級;
    修改歷史:
    • 2002/08/21:第一次完成
    • 2003/02/11:重新編排與加入 FAQ
    • 2004/04/11:已經完成了 Source code 與 Tarball ,開始進行 RPM 與 SRPM 的介紹!(需要耗時多日啊!因為又要進兵營去了!)
    • 2004/04/20:終於給他熬出來啦!又是過了兩個休假期間~啊!給我退伍令、其餘免談!
    • 2005/10/02:舊版的 SRPM 資料已經移動到 此處
    • 2005/10/03:舊版的針對 Red Hat 與 Mandriva 的版本移動到 此處
    • 2005/10/03:將原本去年的版本改為 FC4 為範例的模樣!
    伺服器篇文件
    各版本彙整說明
    CentOS 6.x