2004 年 1 月 01 日
IBM 電子商務(wù)架構(gòu)師 Chris Walden 將通過他在 developerWorks 上發(fā)表的九篇系列文章來指導(dǎo)您如何在 Linux 環(huán)境中運用您的 Windows 操作技巧。在這最后一部分中,我們將下載和編譯一個軟件包,討論自動化包管理的優(yōu)點和缺點,同時了解 RPM 系統(tǒng)。
安裝 Linux 時首先注意到的事情之一,就是 Linux 發(fā)行版本中有如此多可用的包。大多數(shù)發(fā)行版本都附帶了 Linux 操作系統(tǒng)、安裝工具和管理工具。它們還包括 Internet 工具、開發(fā)工具、辦公工具、游戲,以及一些您不曾聽說過的程序。Linux 發(fā)行版本附帶 數(shù)千個可用包的情況并不鮮見。如果您沒有選擇“完整安裝”,則只會安裝這些包的一個子集。
現(xiàn)在您可能想知道“如何刪除不想要的包?如何安裝遺漏了的包?是否能夠使用不是該發(fā)行版本附帶的軟件?”
在安裝 Linux 時,您或許會注意到關(guān)于正在安裝的 RPM 的許多信息。 RPM 代表 Redhat Package Manager(Redhat 包管理器),這是 Redhat 的貢獻,現(xiàn)在已成為管理 Redhat 和 UnitedLinux 以及其他許多發(fā)行版本上的軟件的標(biāo)準(zhǔn)。
RPM 本質(zhì)上就是一個包,包含可以立即在特定機器體系結(jié)構(gòu)上安裝和運行的 Linux 軟件。例如,在“ 第 3 部分. Webmin 簡介”中,我們通過一個 RPM 安裝了 Webmin 包。最初加載到發(fā)行版本中的所有軟件都是通過一個 RPM 來安裝的。
RPM 是文件包。它包括的 .spec 文件提供了關(guān)于包及其功能和依賴關(guān)系(即在該包能夠運行之前必須安裝其他哪些包)的信息。.spec 還包含包中的文件清單,指定這些文件必須加載到系統(tǒng)中的何處,以及它們的初始權(quán)限如何。RPM 還包含安裝前腳本,這是由包開發(fā)人員編寫的。RPM 其次還包含已編譯的二進制文件。最后,RPM 包含了安裝后腳本。
.spec | 安裝前腳本 | 二進制文件 | 二進制文件 | ... | 二進制文件 | 安裝后腳本 |
在安裝 RPM 時,系統(tǒng)首先檢查該包的依賴關(guān)系是否得到滿足。如果不滿足, 安裝過程就會終止,除非您指定了迫使安裝無論如何都要繼續(xù)的選項。
如果一切順利,安裝前腳本就會運行。這個腳本可以做任何事情。它通常創(chuàng)建用戶和目錄。然而,它可以做許多類型的動態(tài)配置,甚至以自定義的方式編譯運行系統(tǒng)的源代碼。
![]() |
|
如果安裝前腳本成功完成,二進制文件將依照清單被復(fù)制到系統(tǒng)上。在復(fù)制完所有的文件和設(shè)置了它們的權(quán)限之后,安裝后腳本就會運行。同樣,這個腳本幾乎能夠做任何事情。
一旦完成所有這些步驟,關(guān)于包的信息就被添加到 RPM 數(shù)據(jù)庫,安裝過程就完成了。使用這種簡單的機制,您能夠執(zhí)行通過更完善的商業(yè)安裝程序所能執(zhí)行的所有功能。
RPM 的優(yōu)雅之處是 RPM 數(shù)據(jù)庫。這個數(shù)據(jù)庫通常位于 /var/lib/rpm 目錄,它包含關(guān)于系統(tǒng)上已安裝的每個 RPM 的信息。這個數(shù)據(jù)庫知道包之間的依賴關(guān)系,當(dāng)刪除某個包將導(dǎo)致其他包無法工作時,它將發(fā)出警告。這個數(shù)據(jù)庫知道最初隨某個包安裝的每個文件以及這些文件在系統(tǒng)上的最初狀態(tài)。它還知道每個包的文檔和配置文件的位置。這聽起來好像是大量的信息,事實上確實如此。但它并不是過多而龐大的。在一個包含 1,066 個包、由 203,272 個文件組成的系統(tǒng)上,數(shù)據(jù)庫文件僅有 45 MB!在加載和卸載包時,RPM 使用這個數(shù)據(jù)庫來檢查依賴關(guān)系。用戶還可以在這個數(shù)據(jù)庫中查詢關(guān)于包的信息。
![]() ![]() |
![]()
|
配合 RPM 包使用的程序被相應(yīng)地命名為 rpm
。 rpm
以多種不同的模式運行,不過最常見的任務(wù)是安裝、升級、查詢、驗證和刪除。
在第一次安裝某個包時,您要使用 -i
或安裝模式。只需將 rpm 指向某個二進制包并執(zhí)行它, rpm 就會把該包安裝到您的系統(tǒng)上。安裝過程一般只需幾秒鐘。我經(jīng)常會在安裝包時使用 -v
(詳細)開關(guān)來提供關(guān)于該過程的更多信息,以及使用 -h
(哈希線)開關(guān)來通過輸出在控制臺上的哈希(#)符號提供安裝進度更新。下面是安裝某個包的例子:
$ rpm -ivh MyPackage-1.0.0.i386.rpm |
就是這個樣子!MyPackage 現(xiàn)在已經(jīng)安裝完成,可供使用了。
![]() |
|
要刪除已安裝的包,可使用 -e
開關(guān)。 rpm
將使用數(shù)據(jù)庫來刪除該包的所有文件。如果有已安裝的其他包依賴正在刪除的包, rpm
將會異常退出。您必須使用 nodeps
開關(guān)來執(zhí)行強制刪除( nodeps
還可以用于強制安裝)。在使用這個開關(guān)來強制安裝或刪除時,務(wù)必 非常 小心。刪除其他包所依賴的包,可能會導(dǎo)致災(zāi)難性的結(jié)果。下面這個命令刪除我們在上面安裝的包:
$ rpm -e MyPackage |
注意,包的刪除并不一定需要它的完整名稱(包括版本號)。安裝時需要完整名稱,因為我們是在引用一個文件名稱。已安裝的包僅通過它們的名稱來引用。包的名稱是版本號之前的所有內(nèi)容。
驗證開關(guān)非常有用。它將包文件的當(dāng)前狀態(tài)與它們在安裝時的原始狀態(tài)作比較。兩種狀態(tài)之間的區(qū)別將用一個代碼來顯示:
S | 文件大小不一致 |
M | 模式不一致(包括權(quán)限和文件類型) |
5 | MD5 校驗和不一致 |
D | 設(shè)備主要/次要編號不匹配 |
L | readLink(2) 路徑不匹配 |
U | 用戶擁有關(guān)系不一致 |
G | 群組擁有關(guān)系不一致 |
T | mTime 不一致 |
如果您對某個包運行 rpm -V
,并且發(fā)現(xiàn)某個可執(zhí)行文件的大小發(fā)生了變化,那可能就是安全漏洞的征兆。
一旦某個包已經(jīng)安裝,嘗試安裝具有相同名稱的包將產(chǎn)生一條消息,指出該包已經(jīng)安裝。 如果想要將某個包升級到更新的版本,可使用 -U
開關(guān)來升級。升級還具有另一個影響。當(dāng)對多個包名稱運行升級時,它將設(shè)法按依賴關(guān)系的順序放置包。換句話說,必需的包將首先安裝。不管某個包是否已經(jīng)安裝,都可以對它使用升級開關(guān),許多人使用它而不是使用 -i
開關(guān)來執(zhí)行安裝和升級。下面是使用升級開關(guān)來加載多個 rpm 包的例子:
$ rpm -Uvh My*.rpm |
在上面的例子中,bMyPackageDep 是 aMyPackageNew 的前提條件,因此盡管文件名稱以相反的順序排列, rpm
也會對它們正確排序。
可以從 rpm 數(shù)據(jù)庫中查詢多種有用的信息。對 rpm 數(shù)據(jù)庫擁有讀訪問權(quán)限的任何用戶都能夠運行查詢。默認(rèn)情況下,全部用戶都擁有讀訪問權(quán)限。要運行一個查詢,可使用 -q
開關(guān)帶上要查詢的包的名稱。這樣將返回該包的版本。
$ rpm -q MyPackage |
包的名稱必須精確匹配,不允許使用通配符。然而,如果記不住包的完整名稱,您可以使用 grep
工具來幫助找到它??梢允褂?-qa
開關(guān)來查詢所有已安裝的包,并用 grep
來管道輸出您能記住的信息。例如:
![]() |
|
$ rpm -qa | grep IBM |
除了版本號外, rpm -q
還可以提供關(guān)于包的其他有用信息。下面就是這樣一些例子:
rpm -q changelog | 顯示包的開發(fā)變更歷史記錄 |
rpm -qc | 顯示包的配置文件 |
rpm -qd | 顯示包的文檔文件 |
rpm -qi | 顯示包描述 |
rpm -ql | 顯示包的文件的列表 |
rpm -qR | 顯示包的依賴關(guān)系 |
還有另一個有趣的查詢命令,它針對文件而不是針對包運行。
rpm -q whatprovides <filename> |
上面這個命令將識別與給定的 filename(文件名)相關(guān)聯(lián)的包。filename 必須包括文件的絕對路徑,因為信息就是以這種方式存儲在 rpm 數(shù)據(jù)庫中的。
![]() ![]() |
![]()
|
從控制臺操作 rpm
很容易,但有時使用圖形用戶界面會更方便。在典型的 Linux 風(fēng)格中,有一些前端程序為 rpm 程序提供界面。每種發(fā)行版本都有一個前端,但是它們各不相同。請參考您的發(fā)行版本文擋,以了解關(guān)于所提供的包管理工具的信息。
![]() ![]() |
![]()
|
Webmin 也為處理 RPM 包提供了一個基于 Web 的簡單前端。
軟件可以從這個界面容易地安裝、刪除和查詢。還可以直接從 URL 站點安裝軟件。如果安裝了諸如 apt
或 Redhat Network 之類的 rpm 增強工具,Webmin 將識別它們并為它們提供一個界面。
![]() ![]() |
![]()
|
由于 Linux 是開放源代碼的操作系統(tǒng),它附帶了編譯軟件所需的所有開發(fā)工具。雖然您使用的大多數(shù)包將以二進制 RPM 的形式提供,但是您并不僅限于使用那些包。如果愿意,您可以為您的系統(tǒng)下載原始源代碼,并以自定義的方式進行編譯。
應(yīng)該對在生產(chǎn)系統(tǒng)上編譯源代碼保持謹(jǐn)慎,因為這樣可能導(dǎo)致問題,或者不再支持系統(tǒng)上正在使用的商業(yè)軟件(比如 IBM DB2)。然而,熟悉從源代碼編譯軟件的過程將使您能夠?qū)浖?yīng)用補丁,以及使用從其他環(huán)境移植過來的包。一旦成功地編譯代碼,創(chuàng)建您自己的 RPM 也是可以做到的!
![]() ![]() |
![]()
|
為演示從源代碼編譯軟件有多簡單,我們將編譯一個名為 Corewars 的模擬游戲(請參閱 參考資料)。下面是來自他們 Web 站點的關(guān)于 Corewars 的說明:“Corewars 是一款模擬游戲,其中許多武士在虛擬的計算機中奔跑時竭力相互攻擊對方??梢圆捎脙煞N類似匯編程序的語言中的一種來編寫武士程序,這兩種語言分別叫做 Corewars 和 Redcode。Corewars 是默認(rèn)語言,更易于學(xué)習(xí)和理解。Redcode 提供更高級和更強大的指令,但是需要更多的時間來學(xué)習(xí)。”
編譯源代碼的第一步是從 Web 站點下載源代碼包:
在代碼下載完成之后,需要展開這個包。
tar -xvzf corewars-0.9.13.tar.gz |
文件將展開到當(dāng)前目錄。標(biāo)準(zhǔn)的做法是將源代碼包含在一個與產(chǎn)品名稱匹配的目錄中。在此例中,源代碼位于一個名為 corewars-0.9.13 的目錄。
首先進入該目錄,找到源代碼和一些文檔、配置腳本和 README 文件。大多數(shù)源代碼包都帶有一個名為 INSTALL 和一個名為 README 的文件。您應(yīng)該在編譯軟件之前首先閱讀這些材料。它們在問題出現(xiàn)之前識別問題,并為您建議正確的編譯和安裝步驟,這樣通??梢宰屇僮咴S多彎路。我在編譯源代碼時遇到的大多數(shù)問題都是因為我沒有遵循那些指導(dǎo)。
通常執(zhí)行的下一步是運行 configure
腳本。 configure
是 Autoconf 包的一部分,包括在 Linux 發(fā)行版本的開發(fā)工具中。這里引用一段 Autoconf 的包描述:“GNU 的 Autoconf 是一個用于配置源代碼和 Makefile 的工具。通過使用 Autoconf,程序員能夠創(chuàng)建可移植和可配置的包,因為建立包的人可以指定各種配置選項。”
configure
腳本在系統(tǒng)上運行一系列測試,以確定為您的發(fā)行版本和系統(tǒng)體系結(jié)構(gòu)編譯包的最佳方式。然后它為您的系統(tǒng)創(chuàng)建一個定制的 Makefile。如果在您的系統(tǒng)上編譯時遇到問題, configure
將會告訴您。 configure
通常允許您自定義將要在編譯中包括的特性,或允許您提供關(guān)于庫或者其他必需文件的位置參數(shù),以便能夠成功地編譯包。下面我們將不帶參數(shù)執(zhí)行 configure
:
./configure |
在系統(tǒng)上多執(zhí)行幾次測試,最終就會編譯成功。下面使用如下命令來生成程序:
make |
如果編譯有錯誤,就需要確定問題并修復(fù)它們。這可能是一件繁瑣的任務(wù),也許需要關(guān)于環(huán)境和程序設(shè)計的大量一般知識。如果一切順利,我們一般會使用以下命令來安裝軟件:
make install |
文件將被復(fù)制到系統(tǒng)中的正確位置,文件權(quán)限會被更新,配置文件將被復(fù)制,文檔也會被添加到手冊頁。
現(xiàn)在通過執(zhí)行該程序來測試我們的勞動成果。它是一個圖形化的程序,因此要在啟動它前運行 X 系統(tǒng)。上面執(zhí)行的 make install
命令應(yīng)該已將程序放到了可執(zhí)行文件路徑中。
corewars |
作為對我們的獎賞,一個圖形化的屏幕應(yīng)該會出現(xiàn)。
corewars 規(guī)則的主題超出了本文的討論范圍,不過您會在手冊頁( man corewars
)中找到關(guān)于這款有趣的模擬游戲的文檔。
corewars 的編譯是一個典型的場景。可能會有其他許多種變化形式,包括在 configure
腳本上使用開關(guān)來調(diào)整要編譯到程序中的特性,以及從 Makefile 使用不同的命令來調(diào)整編譯方式,等等。
由于這個程序不是使用 rpm 來安裝的,因此 rpm 數(shù)據(jù)庫中沒有相應(yīng)的條目。如果某個程序在安裝后沒有按預(yù)期運行,大多數(shù) Makefile 都包括了一個卸載參數(shù)來刪除軟件:
make uninstall |
務(wù)必牢記,使用原始源代碼不會在 RPM 數(shù)據(jù)庫中添加任何內(nèi)容。以這種方式安裝的軟件是非托管的(unmanaged),因此應(yīng)該小心進行。
當(dāng) RPM 被創(chuàng)建時,還有一個稱作源代碼 RPM 的產(chǎn)物。這是一個與源代碼組合在一起的 SPEC 文件,設(shè)計它的目的是為了在一個或多個體系結(jié)構(gòu)上生成程序。這對源代碼和二進制這兩個世界來說是最佳的!對于源代碼 RPM,您可以在系統(tǒng)上定制編譯軟件,但是完成的產(chǎn)品將是一個可安裝的 RPM,而不是原始的二進制。以預(yù)編譯 RPM 的形式可用的大多數(shù)包還以 SRPM 的形式可用。這也許是在 Linux 中軟件跨平臺轉(zhuǎn)移的簡單途徑。當(dāng)您在一個不同的平臺上成功地重新編譯時,可考慮與整個開發(fā)社區(qū)共享完成的 RPM。
![]() ![]() |
![]()
|
如果您是 Linux 新手,安裝軟件的方法與您過去習(xí)慣使用的方法不同。然而,RPM 安裝方法是優(yōu)雅的,同時提供了您很快就會欣賞的新能力。
您應(yīng)該熟悉從控制臺使用 rpm 的選項,不過對于日常使用,有一些前端界面選項使得 rpm 更易于管理。您的發(fā)行版本提供了這樣一個界面,也有其他類似的界面可供使用,比如 Webmin 中的那一個界面。
您并不僅限于使用預(yù)編譯的 rpm,還可以利用 Linux 的開放源代碼性質(zhì),直接從源代碼編譯應(yīng)用程序。對于成熟的項目,編譯通常是很容易的。記住,從源代碼安裝的代碼在 rpm 數(shù)據(jù)庫中沒有相應(yīng)的條目。在使用源代碼時,可考慮使用源代碼 rpm,它組合了已編譯源代碼的強大能力和 rpm 的可管理性。
![]() | ||
![]() | Chris Walden 是位于德克薩斯州奧斯汀的 IBM Developer Relations Technical Consulting(也稱為 dragonslayers )的一名電子商務(wù)架構(gòu)師,該公司為 IBM 商業(yè)伙伴提供教育、實現(xiàn)和咨詢。他致力于 Linux 相關(guān)工作,一有機會就向身邊的人宣傳 Linux 的種種好處。除了完成他的架構(gòu)師的職責(zé)之外,他還精通 Linux 基礎(chǔ)設(shè)施服務(wù)器的各個領(lǐng)域,包括混合平臺用戶環(huán)境下的文件、打印以及其他應(yīng)用服務(wù)等。Chris 有 10 年的計算機行業(yè)經(jīng)驗,從現(xiàn)場支持到 Web 應(yīng)用開發(fā)和顧問,各個領(lǐng)域他都曾涉足。您可以通過 cmwalden@us.ibm.com 與 Chris 聯(lián)系。 |