作者:陳柏菁
E-mail
索引:
7.1 基本的壓縮指令
什麼時候您會想要壓縮檔案呢 ? 那當然是嫌檔案資料太大囉。比如您要寄附加檔案給別人時,就會希望這個檔案能小一點,以加快傳輸效率 ; 另外像在做大量的資料備份時,由於所備份的資料往往都非常可觀,而導致佔用您過多的磁碟空間,此時就可以把這些資料做個壓縮
; 再來像您所提供給 Internet 使用者來下載的檔案,也可以事先將其壓縮,這樣一方面可以節省您的磁碟空間,另一方面也能縮短 Client 端下載的時間。
在 Linux 上頭壓縮檔的附檔名一般為 xx.gz、xx.bz2、xx.tar.gz、xx.tgz 等等,至於這些附檔名的主要作用是為了識別用的,因為藉由附檔名,才能了解當初是使用什麼壓縮工具來產生壓縮檔的,此時您要將它解開或瀏覽其內容時才知道要執行哪個指令。
7.1.1 使用 gzip 壓縮
● gzip: compress
or expand files.
| |
gzip 是 GUN 計劃所研發的一個壓縮檔案的指令,其只能針對個別檔案做壓縮。至於解壓縮時可使用 gunzip
指令。
指令語法:gzip [ -cdlr1~9 ] [ filename ... ]
| |
當您執行 " gzip file " 時,原來檔案
file 就會變成 file.gz 的壓縮檔,其副檔名是自動產生的。 |
參數說明:
| -c |
同於 --stdout。將壓縮或解壓縮後的內容做 standard output,此時原來檔案還是存在。 |
| -d |
同於 --decompress。解壓縮。"gzip -d" 就等於 gunzip。 |
| -l |
同於 --list。列出 gzip 壓縮檔在未壓縮前的大小、壓縮後的大小、壓縮比及未壓縮前的檔名。 |
| -r |
同於 --recursive。對所指定的目錄遞迴地做壓縮。gunzip 亦適用此參數。 |
| -f |
同於 --force。進行強制覆寫。gunzip 亦適用此參數。 |
| -1 ~ -9 |
使用 -9 能產生最佳的壓縮比,而 -1 雖然壓縮比是最低的,但其執行速度最快。預設是 -6。 |
範例說明:
suselinux:/tmp #
cp /etc/passwd file1 ; cp /etc/fstab file2
suselinux:/tmp # gzip file1 file2
suselinux:/tmp # ls
file1.gz file2.gz
| → |
個別對
file1 及 file2 做 gzip 壓縮,壓縮後原來檔案名稱會變成 xx.gz 的壓縮檔。不過如果這兩個壓縮檔原本已存在時,則會詢問您是否要覆蓋。 |
suselinux:/tmp # gzip -l file1.gz
| compressed |
uncompressed |
ratio |
|
uncompressed_name |
| 520 |
1132 |
56.2% |
|
file1 |
suselinux:/tmp # gzip -d file1.gz ←
解壓縮。
suselinux:/tmp # ls
file1 file2.gz
| → |
file1.gz
已改變成 file1。不過在進行解壓縮之前,如果 file1 已存在,則會詢問您是否要覆蓋。 |
suselinux:/tmp # gunzip file2.gz
| → |
可用單一指令
gunzip 來達到與 " gzip -d
" 同樣的效果。 |
suselinux:/tmp # ls
file1 file2
suselinux:/tmp # gzip -c file1 >
file1.gz
| → |
將
file1 壓縮後的內容輸出到 file1.gz。注意噢,file1 還是存在噢 ! |
suselinux:/tmp # cat file1 file2 | gzip
> file3.gz
| → |
將
cat 指令的輸出當成 gzip 指令的輸入,並將 gzip 壓縮過後的內容轉向輸出到 file3.gz。 |
suselinux:/tmp # gzip -c file1 file2
> file4.gz
suselinux:/tmp # gzip -c file1 >
file5.gz
suselinux:/tmp # gzip -c file2 >>
file5.gz
| → |
先將
file1 壓縮後的內容輸出至 file5.gz,再將 file2 壓縮後的內容附加至 file5.gz。 |
suselinux:/tmp # gzip -cd file1.gz
| → |
將
file1.gz 解壓縮後的內容做 standard output,這樣您就可以看到壓縮檔的內容了。 |
suselinux:/tmp # gunzip -c file1.gz
| → |
使用
"gunzip" 來代替 "gzip -d",所以跟上面的執行結果是相同的。 |
suselinux:/tmp # zcat file1.gz
| → |
zcat
是專門用來瀏覽 gzip 壓縮檔內容的指令。 |
suselinux:/tmp # mkdir -p dir/dir1
suselinux:/tmp # cp /etc/passwd dir/file1
; cp /etc/passwd dir/dir1/file2
suselinux:/tmp # gzip -r dir
| → |
遞迴地壓縮
dir 目錄中的檔案。執行完後可至 dir 及 dir1 目錄下檢視看看。如想遞迴解壓縮的話,則執行 "gunzip
-r dir" 即可。 |
|
|
7.1.2 使用 bzip2 壓縮
● bzip2:
| |
這是另一個針對個別檔案做壓縮的指令,且其壓縮效果比 gzip 好噢 ! 至於解壓縮時可使用 bunzip2
指令。
指令語法:bzip2 [ -cdkv1~9 ] [ filenames ... ]
| |
當您執行 " bzip2 file " 時,原來檔案
file 就會變成 file.bz2 的壓縮檔,且其副檔名也是自動產生的。 |
參數說明:
| -c |
同於 --stdout。將壓縮或解壓縮後的內容做 standard output,此時原來檔案還是存在。 |
| -d |
同於 --decompress。解壓縮。"bzip2 -d" 就等於 bunzip2。 |
| -k |
同於 --keep。保留原來檔案。bunzip2 亦適用此參數。 |
-v |
同於 --verbose。 |
| -f |
同於 --force。進行強制覆寫。bunzip2 亦適用此參數。 bzip2 (bunzip2) 預設不會做這個動作。 |
| -1 ~ -9 |
與 gzip 意思相同。預設為 -9。 |
範例說明:
suselinux:/tmp # rm
-rf *
suselinux:/tmp # cp /etc/passwd file1
; cp /etc/fstab file2
→ 將剛剛的檔案全部清除,重新再做一次。
suselinux:/tmp # bzip2 file1 file2
suselinux:/tmp # ls
file1.bz2 file2.bz2
→ 產生兩個
xx.bz2 的壓縮檔。
suselinux:/tmp # bzip2 -d file1.bz2
; bunzip2 file2.bz2
suselinux:/tmp # ls
file1 file2
→ 解壓縮後又回覆到原來的檔案名稱。
suselinux:/tmp # bzip2 -k file1
suselinux:/tmp # ls
file1 file1.bz2 file2
→ 加上
-k 來保留原來的檔案名稱 file1。
suselinux:/tmp # bzip2 -v file2
file2 : 3.970:1, 2.015 bits/byte, 74.81% saved, 1747 in, 440 out.
→ 壓縮同時還可以看出壓縮比率。
suselinux:/tmp # ls
file1 file1.bz2 file2.bz2
→ 目前
file1 及 file1.bz2 都存在,來實驗一下能否覆寫:
suselinux:/tmp # bzip2 file1
bzip2: Output file file1.bz2 already exists.
suselinux:/tmp # bunzip2 file1.bz2
bunzip2: Output file file1 already exists.
→ 看到結果了吧
! 如要強制覆寫就加上 -f 參數:
suselinux:/tmp # bunzip2 -f file1.bz2
suselinux:/tmp # bzip2 -cd file2.bz2
suselinux:/tmp # bunzip2 -c file2.bz2
suselinux:/tmp # bzcat file2.bz2
→ 上面這三種方式都可以瀏覽
file2.bz2 的內容。
suselinux:/tmp # bunzip2 file2.bz2
suselinux:/tmp # ls
file1 file2
→ 再把
file2.bz2 解開來準備做以下的實驗:
suselinux:/tmp # bzip2 -c file1 file2
> file3.bz2
suselinux:/tmp # cat file1 file2 | bzip2
> file5.bz2
→ 這應該沒問題吧
! |
|
7.2 備份工具
講到備份,那可說是系統管理上非常重要的一環。平常如果有備份的習慣,萬一哪天因某些因素造成您系統資料的流失時,就可以執行備份還原來恢復系統原本的狀態。
一般在執行備份時都會將備份的工作寫到排程裡,這樣子排程時間一到,系統就會自動做這些工作,而不須我們操心,不過話雖如此,您還是要定期的去檢視您的備份檔,以了解是否備份完整。
而能拿來做備份的工具有很多,或許您會問,那哪個工具比較好用呢 ? 其實這並沒有一定的答案,因為這要視您實際的需求及平常使用習慣來做決定,如果您只是想在磁碟上備份幾個還不算大的檔案,那使用
cp 指令就行了。但有時侯因考慮到備份容量、備份還原的方便性、… 等等的問題,所以可能會使用不同的工具來達到您的目的。以下我們就跟大家介紹幾個常見的備份指令。
7.2.1 tar 指令
● tar:The GNU version
of the tar archiving utility.
| |
tar 指令可以將一些檔案目錄一起打包到一個檔案內,而所建立的這個檔案就稱為 archive file (tar file)。我們也可以使用
tar 來將資料打包至儲存媒體上,比如磁帶機之類的裝置 (如 /dev/st0、/dev/ht0)。一個好的系統管理者應該都有做備份的習慣,而
tar 將是您最好的選擇之一。 註:所謂的 archive file 是泛指那些包含很多檔案目錄資料的檔案。
指令語法:tar [-] [cvftxrzjCXPp] tarfile filename… dirname…
| |
使用 tar 所建立起來的 tarfile 名稱 (包括其附檔名),需自行指定,一般都是用 xx.tar,那如果此
tarfile 有使用 gzip 去壓縮,則可指定為 xx.tar.gz 或 xx.tgz,當然用 bzip2 壓縮的話就可指定為
xx.tar.bz2 ; 而指定這些不同的附檔名主要是為了方便管理,比如當您看到 xx.tar.bz2 就知道這個 tarfile
有使用 bzip2 壓縮過,這樣您才知道要如何解開它或如何瀏覽其內容。 |
參數說明:
| -c |
同於 --create。用來建立一個新的 archive file。 |
| -v |
同於 --verbose。顯示執行過程。 |
| -f |
同於 --file=filename。表示其後要指定一個 archive file 或 device name。使用 tar
做備份時最基本的就是 "-cvf" 這三個參數的組合。 |
| -t |
同於 --list。列出 archive file 的內容。 |
| -x |
同於 --extract。從 archive file 中解開這些被打包的檔案目錄,也就是備份還原啦 ! |
| -r |
同於 --append。附加檔案至 archive file 檔案內容的後面。 |
| -k |
同於 --keep-old-files。 執行備份還原時,不覆蓋已經存在的檔案。預設是會覆蓋的。 |
| -z |
同於 --gzip 或 --ungzip。用 gzip 來壓縮 archive file。比如您要建立一個用 gzip 壓縮的
archive file,就可搭配 "-zcvf" 參數來使用 ; 反過來說要解開當初用
gzip 壓縮的 archive file,則使用 "-zxvf" 即可。 |
| -j |
同於 --bzip2 或 --bunzip2。用 bzip2 來壓縮 archive file。比如您要建立一個用 bzip2
壓縮的 archive file,就可搭配 "-jcvf" 參數來使用 ; 反過來說要解開當初用
bzip2 壓縮的 archive file,則使用 "-jxvf" 即可。 |
| -C |
同於 --directory=DIR。備份還原至 -C 所指定的目錄之中。如未指定,則預設會還原至現在所在的工作目錄之中。 |
| -X |
同於 --exclude-from=filename。執行備份時,可以事先將欲排除備份的檔案目錄設定在一個檔案內,然後再使用 "
-X file " 來排除就行了。 |
| -g |
同於 --listed-incremental=filename。做遞增備份時所指定的備份紀錄檔案。 |
範例說明:
suselinux:~
# mkdir /backup
suselinux:~ # tar cvf /backup/bck.tar
/etc/passwd /home
| tar : Removing
leading ' / ' from member names |
→ |
tar 會先將備份路徑中最前面的 " / " 移除,然後再備份至 tar file 裡,這也是為何您在執行過程所看到的
etc/passwd、home/barry、… 最前頭都少個 " / " 的原因。 |
etc/passwd
home/barry/
home/barry/bin/
home/barry/Documents/
home/barry/Documents/.directory
home/barry/.exrc
home/barry/.bashrc
: 略
→ 將 /etc/passwd 檔案及 /home 目錄備份至 bck.tar 裡。如您習慣在參數前加上
" - ",如 " -cvf " 也是可以。
suselinux:~ # cd /backup
suselinux:/backup # tar tf bck.tar
→ 列出
tar file 裡所打包的檔案目錄清單。
suselinux:/backup # tar rvf bck.tar
/etc/fstab /var/spool/mail
→ 附加檔案至
tar file 裡。如果此時您是使用 " cvf " 的話,可是會從新建立起一個新的
tar file 噢 ! 那原來的 tar file 當然就被取代了。
suselinux:/backup # tar --delete -f
bck.tar etc/fstab
→ 將
fstab 檔案從 tar file 中移除。
suselinux:/backup # tar xvf bck.tar
etc/passwd
→
只解開 passwd 檔案。
suselinux:/backup # ls
bck.tar etc
→ 解開後多了一個
etc 目錄出來,而此目錄的內容就是 passwd 檔案。
suselinux:/backup # tar xvf bck.tar
→ 將
tar file 全部解開。
suselinux:/backup # ls
bck.tar etc home var
執行備份還原時,對於已經存在的檔案預設是會覆蓋的 ; 您可以馬上做個實驗:先修改
/backup/etc/passwd,然後再執行一次備份還原,看看 passwd 的內容有無被覆蓋 ? 另外對於其他的檔案目錄則是不受影響,比如先在
/backup/etc 目錄中建立一個 testfile 檔案,然後再執行備份還原,結果這個 testfile 還是存在。
如果您不想覆蓋已經存在的檔案,可加上 " -k
" 參數:
suselinux:/backup # tar xkvf bck.tar
etc/passwd
etc/passwd
tar: etc/passwd: Cannot open: File exists
tar: Error exit delayed from previous errors
針對剛剛所建立起來的 tar file,可以使用 gzip 或 bzip2
對其進行壓縮,以 gzip 來做範例好了:
suselinux:/backup # gzip bck.tar
suselinux:/backup # ls
bck.tar.gz etc home var
→ 結果就產生了
bck.tar.gz。這種被壓縮過後的 tar file,一般就稱為 tarball。
我們也可以使用 tar 指令來直接進行打包兼壓縮:
suselinux:/backup # tar zcvf test.tar.gz
/etc/passwd /var/spool/mail
→ 將
tar file 進行 gzip 壓縮。
suselinux:/backup # tar jcvf test.tar.bz2
/etc/passwd /var/spool/mail
→ 將
tar file 進行 bzip2 壓縮。
suselinux:/backup # tar ztf test.tar.gz
→ 瀏覽
tarball 清單。如欲瀏覽 test.tar.bz2 的清單,則執行 " tar jtf test.tar.bz2
"。
suselinux:/backup #
gzip
-cd test.tar.gz
suselinux:/backup # zcat test.tar.gz
→
瀏覽
tarball 中的檔案內容。如欲瀏覽 test.tar.bz2 的檔案內容,則執行 " bzip2 -cd
test.tar.bz2 " 或 " bzcat test.tar.bz2
"。
suselinux:/backup # tar zxvf test.tar.gz
etc/passwd
→
只解開
passwd 檔案。針對 bzip2:" tar jxvf test.tar.bz2 etc/passwd
"。
suselinux:/backup # tar zxvf test.tar.gz
→
將整個
tarball 解開。針對 bzip2:" tar jxvf test.tar.bz2
"。
suselinux:/backup # zcat test.tar.gz
| tar xvf -
→
這種另一種解開
tarball 的做法。
使用 -C 參數來指定要備份還原至哪個目錄:
suselinux:/backup # tar -C
/tmp -jxvf test.tar.bz2
有些時候在執行目錄備份時,您會想排除目錄中的某些檔案目錄,也就是不想將其備份進去的意思,此時該怎麼做呢
? 我們以 /home 做例子好了,假使現在要備份 /home,但 /home/user01 及 /home/user02 不想備份進去,那麼您可以事先將這兩個欲排除的目錄寫入一個檔案中:
suselinux:~ # vi excludefile
/home/user01
/home/user02
再搭配 " -X " 來進行備份:
suselinux:~ # tar -X
excludefile -zcvf /backup/home.tar.gz
/home
在執行備份工作時,為了增加備份的效率,可以考慮使用遞增備份 (incremental
backup) 的方式,所謂的遞增備份就是此次備份只針對前面幾次備份完後尚有異動的資料做備份而已 ; 當您備份資料很多時,使用這種方式會顯得特別的有效率。進行以下的實驗時,您可以在每次遞增備份完後,嘗試修改檔案目錄內容,然後再進行下一次的備份:
suselinux:/backup # tar -g
increfile -zcvf home.tgz /home
→
使用
" -g " 參數來將初次備份的記錄存放在 increfile 內。
suselinux:/backup # tar -g increfile
-zcvf home1.tgz /home
→
執行第一次遞增備份。請記得還是要加上
" -g " 參數。
suselinux:/backup # tar -g
increfile -zcvf home2.tgz /home
→
執行第二次遞增備份。
接著把 /home 的內容清除掉,然後執行備份還原 (請從首次所做的備份還原起):
suselinux:/backup # rm -rf /home/*
suselinux:/backup # tar -C
/ -zxvf home.tgz
suselinux:/backup # tar -C
/ -zxvf home1.tgz
suselinux:/backup # tar -C /
-zxvf home2.tgz
自己練習看看吧 ! |
|
7.2.2 cpio 指令
● cpio:copy
files to and from archives.
| |
備份檔案至 archives 或從 archives 執行備份還原。archive 可以是檔案或磁帶機。
cpio 會從標準輸入取得檔案名稱列表 (一個檔案名稱一行),並將結果輸出至 archive。執行 cpio 時,我們經常會搭配
find 指令來使用,這樣備份進去的檔案目錄就會包含整個完整路徑噢,因此在執行備份還原時也特別方便。
參數說明:
| -o |
建立一個新的 archive。 |
| -i |
將資料從 archive 取出,也就是備份還原囉 ! |
| -t |
檢視 archive 內容。 |
| -F |
此參數後需指定一個 archive file。 |
範例說明:
suselinux:~
# find /home/barry /home/mary | cpio
-o > /backup/bck.cpio
suselinux:~ # find /home/barry /home/mary
| cpio -oF /backup/bck.cpio
→ 將 /home/barry 及 /home/mary 備份至 /backup/bck.cpio。以上兩種做法都行噢。
suselinux:~ # cpio -t < /backup/bck.cpio
suselinux:~ # cpio -tF /backup/bck.cpio
→ 查看 /backup/bck.cpio 的內容。
suselinux:/home # rm -rf barry
mary
→ 將 barry 及 mary 家目錄刪除,然後再進行以下的備份還原測試。
suselinux:~ # cpio -i < /backup/bck.cpio
suselinux:~ # cpio
-iF /backup/bck.cpio
→ 進行備份還原囉 ! 自己做看看吧 ! |
|
7.2.3 dd 指令
● dd:
convert and copy a file
| |
這是另一個複製的工具,且其具有某些特色是其他備份工具做不來的,比如備份 MBR 磁區或者是某個 partition
的 Boot Sector。 常用參數:
| if=FILE |
讀取 FILE 的內容來代替 stdin。 |
| of=FILE |
寫入 FILE 以替代 stdout。 |
| ibs=BYTES |
一次讀取多少 bytes 的區塊大小。 |
| obs=BYTES |
一次寫入多少 bytes 的區塊大小。 |
| bs=BYTES |
ibs 及 obs 都相同。也就是讀取與寫入多少 bytes 的區塊大小是一樣的。 |
| count=BLOCKS |
只複製所指定讀取的區塊數大小。 |
範例說明:
suselinux:~ # ls
-l /etc/passwd ← 先了解
/etc/passwd 的檔案大小為 1299 bytes。
-rw-r--r-- 1 root root 1299 Oct 2 23:52 /etc/passwd
suselinux:~ # dd if=/etc/passwd of=/tmp/file1
bs=1024
1+1 records in
1+1 records out
| → |
指定讀取與寫入的區塊大小為 1024
bytes。因 /etc/passwd 檔案大小為 1299 bytes,需使用到兩個大小為 1024 bytes 的區塊,所以您會看到
"1+1 records in",這表示讀取兩個區塊紀錄,而 "1+1 records out"
則表示寫入兩個區塊紀錄。若 bs 不指定,預設為 512 bytes。 |
suselinux:~ # dd if=/etc/passwd of=/tmp/file2
bs=512 count=2
2+0 records in
2+0 records out
| → |
指定讀取與寫入的區塊大小為 512
bytes,並且使用 count 去指定讀取兩個區塊的內容,也就是只複製 1024 bytes 啦。咦,奇怪,上面顯示的怎麼是
"2+0" 而不是 "1+1" 啊,因為兩個 512 bytes 的區塊資料都有填滿,如果有一個未填滿才會顯示
"1+1"。 |
suselinux:/tmp # dd if=/etc/passwd of=/tmp/file3
ibs=512 obs=2k count=2
2+0 records in
0+1 records out
| → |
指定讀取兩個 512 bytes
的區塊大小,換言之就是只複製 1024 bytes ; 而 obs=2k 表示要寫入的區塊大小為 2048 bytes。 |
|
建立 swap file
| |
一般我們所熟知的是使用分割區來作 swap 空間,而 dd 指令能幫您使用檔案來做 swap 空間噢。如果您覺得目前的
swap 空間太少,想要多增加個 100 M,這時候您就可以這麼做:
suselinux:~ #
dd if=/dev/zero of=/tmp/swapfile bs=1000k count=100 ←
先規劃出 swapfile 空間的大小。
100+0 records in
100+0 records out
suselinux:~ # mkswap /tmp/swapfile ←
對 swapfile 進行格式化。
Setting up swapspace version 1, size = 102395 kB
suselinux:~ # swapon /tmp/swapfile ←
啟用 swapfile。
最後 可執行 " free " 指令去看看 swap 空間有沒有增加
100 M。 |
如想在下次開機時能自動啟用此 swap file,那就在 /etc/fstab 內補上一行設定:
| /tmp/swapfile swap
swap defaults 0 0 |
|
備份 MBR 磁區
| |
真是神奇,dd 居然也能備份 MBR 磁區,而且還很簡單:
suselinux:~ # dd
if=/dev/hda of=mbrbck bs=512 count=1
→ 可不要忘了指定 count=1 啊,不然會變成備份整顆硬碟噢。
suselinux:~ # file mbrbck
mbrbck: x86 boot sector, code offset 0x48 |
如果您要備份的是 partition 上的 boot sector,請如法炮製一番,至於應用範例可參考 6.2.1 小節中 [使用
NT Loader 來擔任 Boot Manager ] 的相關說明。 |
|
7.2.4 備份時需考慮事項
備份是需要經過事先規劃的,而您在制定備份策略時,可能需要先做個全盤考慮,這樣的備份才會比較完善。以下我們列出幾點來給各位參考:
| 1. |
欲備份的資料:
您是想對整顆硬碟、某幾個 partition 還是某些檔案做備份,這可是要好好的想一想啊。如果只是想針對比較重要的資料做備份時,則首選當然是針對
/etc、/home、/srv、/var、/root、/boot 這幾個目錄來下手,另外如果您有把軟體安裝在 /usr/local 中的話,也可把這個目錄備份起來。至於不需備份的目錄有
/dev、/proc、/mnt、/media、/tmp 等,另外 swap 當然也不需備份啦 ! |
| |
|
| 2. |
要備份到哪裡:
打算要備份至同主機的另一顆硬碟、不同主機的硬碟、異地備援或者是像 CD-ROM、MO、Tap、… 這一類的儲存媒體。 |
| |
|
| 3. |
採取的備份模式:
一般常見到的備份方式有完全備份 (full backup)、部分備份 (partial backup)、遞增備份 (incremental
backup)、差異備份 (differential backup)。其意義如下:
完全備份:將整個檔案系統備份下來。
部分備份:只針對某個目錄或分割區進行備份。
遞增備份:針對上次完全備份及遞增備份後資料有異動的地方進行備份。
差異備份:針對上次完全備份後資料有異動的地方進行備份。 |
| |
|
| 4. |
多久備份一次:
這要視您資料的重要性才能做決定。比如您是以 full backup 及 incremental backup 來搭配使用的話,可以規劃每個月的第一週進行
full backup,爾後的每一週進行一次 incremental backup,當然如果是特別重要的資料,則可能要額外的進行每天備份囉
!
|
7.3
在 Linux 上安裝軟體套件
大家應該都有在 Windows 中安裝軟體的經驗,就是把軟體下載回來後,直接執行安裝程式,然後一直按 [下一步 ],最後就很輕易地完成安裝了。因為
Windows 所提供的軟體其原始碼未公開,當然您就無法修改它,所以在安裝時您只能按照 [公式化] 的步驟去進行,那在 Linux 中又如何呢 ? 還記得
Linux 的一大特色:Open Source 吧 ! 因為大部分的 Linux 軟體其原始碼是公開的,所以可以依照自己的需求去做調整,不論您想修改軟體的原始碼或改變安裝的路徑都是可行的。底下我們會介紹兩種在
Linux 上頭安裝軟體的方式,一種是下載 tarball 套件來安裝,另一種是利用發行商所提供的 RPM 套件來安裝。
7.3.1 安裝 Tarball
tarball 這個名稱應該還記得吧 ! 不過網路上提供給我們下載的 tarball,可不是只包含單純的文字檔案而已噢,而是包括程式的原始碼、含括檔、測試工具、安裝說明及其他的說明文件等等。通常提供者會將以上所提及的這些內容給它集中在一個目錄中,然後使用
tar 來把這個目錄打包起來並壓縮,所以當您下載回來後第一個動作就是把 tarball 解開,然後切換至這個目錄上,爾後所進行的編譯安裝步驟就是在這個目錄下進行的。
由於 tarball 裡頭含有 C 語言的原始碼,所以免不了要使用編譯器 (compiler) 來對其進行編譯的動作,這樣編譯完成後的 binary file
才能夠在 Linux 系統中被執行 ; 而目前被廣為使用的 compiler 是 GNU 計劃中的 gcc 程式,它是用來針對 C 及 C++ 進行 compile
的。
接著來認識一下原始碼編譯的流程:
| 1. |
先使用 vi 去編輯 C 的原始碼檔案,且檔名必需用 " .c " 的附檔名,如 barry.c。 |
| 2. |
執行 gcc 來對 xxx.c 進行編譯。 |
| 3. |
編譯過程中會產生目的檔 (xxx.o),連結器會將此目的檔與函式庫做個連結。 |
| 4. |
最後就會產生可執行的 binary file。 |
舉個簡單的例子,首先請您先使用 vi 去編輯 barry.c:
suselinux:/tmp # vi
barry.c
#include <stdio.h>
main(void)
{
printf("Hello,everybody!\n");
printf("My name is barry.\n");
} |
再來執行 gcc (請確定您 gcc 相關套件有安裝):
suselinux:/tmp #
gcc -c barry.c
suselinux:/tmp # ls
barry.c barry.o ← 產生目的檔。
suselinux:/tmp # gcc -o barry barry.o
suselinux:/tmp # ls
barry.c barry.o barry ←
產生了 binary file。
suselinux:/tmp # ./barry
Hello,everybody!
My name is barry. |
如果您要直接產生
binary file,也可執行 "gcc -o barry barry.c"。或許您又會有疑問,既然可以直接產生
binary file,那為何上面的範例不這樣做呢 ? 因為實際上程式設計師所編寫的原始碼檔案,在編譯過程會使用到其他原始碼檔案所產生的目的檔,所以才會採用範例中的方式來產生
binary file。
不過 tarball 裡的原始碼檔案往往為數不少,為了簡化我們的操作程序,可以使用 make 指令來執行這項工作,但您需要先去編輯
Makefile 檔案,因為 make 會讀取 Makefile 或 makefile 的內容:
suselinux:/tmp # vi
Makefile
target_first: barry
barry:
gcc -c barry.c
gcc -o barry barry.o
install:
install -m 755 barry /home/mary
uninstall:
rm -f /home/mary/barry
distclean:
rm -f barry barry.o |
在 Makefile 裡頭,包含了很多 target,您在 " : " 左邊所看到的都是屬於 target,至於這個
target 所要執行的程式則是設定在 target 底下,且必須使用 Tab 鍵來取間格。
當您執行 make 指令時,會使用 Makefile 裡所定義的第一個 target,以這個範例來說就是 target_first,而
target_first 又指向 barry 這個 target,所以最後會執行 barry target 底下的程式。
當執行 make install 時,那當然就執行 install target 其下的程式囉 ! 所以 install
程式就會把 barry 這個 binary file 複製到 /home/mary 目錄裡,並指定此 binary file 的權限為 755。最後的
"make uninstall" 及 "make distclean"
應該不用解釋了吧 !
接著就來做個測試:
suselinux:/tmp # make
← 執行編譯。
gcc -c barry.c
gcc -o barry barry.o
suselinux:/tmp # ls
Makefile barry barry.c barry.o
← 多個
barry 的目的檔及執行檔。
suselinux:/tmp # make install ←
執行安裝。
install -m 755 barry /home/mary
suselinux:/tmp # ls /home/mary
← barry 已被複製到
/home/mary 中了。
Documents barry bin public_html
suselinux:/tmp # make uninstall
rm -f /home/mary/barry
suselinux:/tmp # make distclean
rm -f barry barry.o |
實作練習:
首先使用 ncftp 程式來連上 FTP 站台 (請確認您 ncftp 套件有安裝):
suselinux:~ #
ncftp ftp.proftpd.org
NcFTP 3.1.7 (Jan 07, 2004) by Mike Gleason (http://www.NcFTP.com/contact/).
Connecting to 81.223.20.36...
ProFTPD 1.3.0rc3 Server (proftpd.org Project) [81.223.20.36]
Logging in...
Anonymous access granted, restrictions apply.
Logged in to ftp.proftpd.org.
ncftp / > ls
| MIRMON.PROBE |
contrib/ |
distrib/ |
historic/ |
| README.MIRRORS |
devel/ |
docs/ |
patches/ |
ncftp / > cd distrib/
ncftp /distrib > ls
packages/ source/
ncftp /distrib > cd source/
ncftp /distrib/source > get proftpd-1.3.0rc2.tar.gz
proftpd-1.3.0rc2.tar.gz: ETA: 0:05 1.28/ 1.76 MB 93.00 kB/s
ncftp /distrib/source > by
You have not saved a bookmark for this site.
Would you like to save a bookmark to:
ftp://ftp.proftpd.org/distrib/source/
Save? (yes/no) no
Not saved. (If you don't want to be asked this, "set confirm-close
no")
如果以後您不想再看到這個詢問訊息,可於 ncftp 提示號下輸入 " set
confirm-close no "。
suselinux:~ # |
再來進行解壓縮:
suselinux:~ #
tar zxvf proftpd-1.3.0rc2.tar.gz
suselinux:~ # cd proftpd-1.3.0rc2/
suselinux:~/proftpd-1.3.0rc2 #
→ 等一下的編譯、安裝步驟都是在 proftpd-1.3.0rc2 這個目錄下完成的。 |
在 proftpd-1.3.0rc2
這個目錄中存在著一支很重要的測試工具叫 configure (是一支 script),它是用來偵測您的作業環境,並自動產生
Makefile (或 makefile) 檔案,待會兒不論進行編譯、安裝、移除等工作,可都是靠 Makefile 來作為執行的依據。所以萬一執行
configure 的過程中發現有任何錯誤訊息報告的話,那麼後面要繼續進行的步驟可能就會有問題了。
另外可以參考目錄中的 README 或 INSTALL 檔案,裡邊有詳細的安裝步驟介紹。最後您可查看一下那些子目錄的內容,包括很多的原始碼檔案及含括檔,這些都是等一下的編譯過程需要用到的。
完成以上動作後,開始按照以下步驟進行:
| |
1. |
執行 configure script:
suselinux:~/proftpd-1.3.0rc2
# ./configure --prefix=/usr/local/proftpd
checking build system type... i686-pc-linux-gnu
checking host system type... i686-pc-linux-gnu
checking target system type... i686-pc-linux-gnu
checking for gcc... gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
:略
config.status: creating utils/ftptop.1
config.status: creating utils/ftpwho.1
config.status: creating Makefile
config.status: creating Make.rules
config.status: creating config.h
config.status: executing default commands
--prefix 是用來指定安裝時候的位置,這裡我是把它集中在 /usr/local/proftpd
目錄中,這樣比較方便管理。如未指定安裝路徑的話,預設是會安裝在 /usr/local 下的相關子目錄中。至於其他詳細用法,可執行 "./configure
-h" 自行查閱。 |
|
| |
|
|
| |
2. |
進行編譯:
suselinux:~/proftpd-1.3.0rc2
# make
echo \#define BUILD_STAMP \"`date`\" >include/buildstamp.h
cd lib/ && make lib
make[1]: Entering directory `/root/proftpd-1.3.0rc2/lib'
gcc -DHAVE_CONFIG_H -DLINUX -I.. -I../include -O2 -Wall -c pr_fnmatch.c
gcc -DHAVE_CONFIG_H -DLINUX -I.. -I../include -O2 -Wall -c sstrncpy.c
gcc -DHAVE_CONFIG_H -DLINUX -I.. -I../include -O2 -Wall -c strsep.c
gcc -DHAVE_CONFIG_H -DLINUX -I.. -I../include -O2 -Wall -c vsnprintf.c
:略 |
|
| |
|
|
| |
3. |
執行安裝:
suselinux:~/proftpd-1.3.0rc2
# make install
cd lib/ && make lib
make[1]: Entering directory `/root/proftpd-1.3.0rc2/lib'
make[1]: Nothing to be done for `lib'.
make[1]: Leaving directory `/root/proftpd-1.3.0rc2/lib'
cd src/ && make src
make[1]: Entering directory `/root/proftpd-1.3.0rc2/src'
:略
/usr/bin/install -c -s -o root -g root -m 0755
ftpcount /usr/local/proftpd/bin/ftpcount
/usr/bin/install -c -s -o root -g root -m 0755 ftpshut /usr/local/proftpd/sbin/ftpshut
/usr/bin/install -c -o root -g root -m 0644 ./src/proftpd.8 /usr/local/proftpd/man/man8
/usr/bin/install -c -o root -g root -m 0644 ./utils/ftpshut.8 /usr/local/proftpd/man/man8
:略 |
|
整個 tarball 的安裝步驟大致如此。接著您可直接切換到 /usr/local/proftpd 去看看,裡邊是不是包含
bin、sbin、man、etc、var 等
目錄。不過為了將來操作上的方便,尚須做一點調整,以方便您直接輸入指令及查看 manpage:
suselinux:/etc/skel #
cp .profile .bashrc /root
→ 這兩個檔案如果不存在就直接複製過來。
suselinux:~ # vi .profile
PATH="$PATH:/usr/local/proftpd/bin:/usr/local/proftpd/sbin"
export PATH
suselinux:~ # source .profile
suselinux:~ # vi /etc/profile
MANPATH=`test -x /usr/bin/manpath && /usr/bin/manpath -q`:/usr/local/proftpd/man
← 補上去即可。
export MANPATH
suselinux:~ # source /etc/profile |
如果您覺得這樣集中管理的方式不太習慣 ( 因為還要調整路徑 ),那麼當初在執行 configure script 時可以這麼做:
suselinux:~/proftpd-1.3.0rc2 #
./configure --prefix=/usr --sysconfdir=/etc \
> --mandir=/usr/share/man |
這樣一來,編譯好的程式就會放在 /usr/bin、/usr/sbin 裡邊,設定檔就存放在 /etc 目錄,manpage
當然就在 /usr/share/man 底下啦。
7.3.2 RPM 套件管理
RPM 為 RedHat Package Manager
的簡寫,是由 RedHat 公司所發展,它是由發行商事先將檔案、編譯過的執行程式、說明文件及相關函式庫等打包到套件裡頭,且這些檔案的安裝路徑都幫您規劃好了,另外也會記載著套件的相依性。在我們安裝
RPM 套件時也只不過是把這些相關的檔案直接安裝在該安裝的位置而已,因此安裝速度會比 tarball 快上許多,也由於它的方便性使得一些 distribution
相繼採用。
RPM 的資料庫是在 /var/lib/rpm 目錄中,今天如果安裝了一個新的套件,那麼這個套件資訊就會記錄在資料庫裡,將來要是想查詢、移除、升級套件時,也都會使用到資料庫內所記載的資訊。
雖然使用 RPM 來安裝非常方便,但相對的也有一些缺點,其中最為人所詬病的是他的套件相依性問題,比如您下載了套件 A,要安裝時卻出現套件 A 需要相依套件
B 的訊息,所以只好再去下載套件 B,結果好不容易將套件B下載回來了,而在安裝套件 B 時又出現套件 B 需要套件 C 的訊息,進行至此可能會想放棄吧
! 不過在 SuSE 裡頭如您要安裝的套件就在光碟裡,那使用 YaST 去安裝時會自動幫您抓出相依的套件,可以多加利用。
另外 RPM 還有個 distribution 的問題,由於各家 distribution 所推出的 RPM 是依照他們所發行的那個版本的環境來製作 RPM
的,因此您要是想把 SuSE 的 RPM 安裝在 RedHat 上頭可能就會有問題囉 ! 即使是同一個 distribution 也未必可行,比如 SuSE
9.3 的 RPM 安裝在 SuSE 8.2 就不一定行得通。所以今天您想安裝的軟體找不到合適的 RPM 套件時,那只好考慮下載 tarball 來安裝囉
!
以下提供兩個可以找到各版本 RPM 套件的網站:
http://rpmfind.net/
http://www.rpmseek.com/index.html
那 SRPM 又是什麼呢 ? 就是 Source RPM,也就是套件裡頭包含了一些原始碼,所以 SRPM 須先經過編譯打包的動作,等產生了 RPM 後才能開始安裝。
接著我們來認識一下 RPM 套件到底長什麼樣子,以 ncftp-3.1.7-40.1.i586.rpm 套件檔案 (package file) 來說明好了:
| ncftp |
套件名稱 (package name)。 |
| 3.1.7 |
套件版本 (version)。 |
| 40.1 |
修正版 (release)。 |
| i586 |
i 是指與 intel 相容的 CPU,586 則是指 CPU 等級,也就是說 xxx.i586.rpm 的 RPM 當初是以 586 電腦作為測試的平台,以尋求最佳化的設定。另外還常看到
i386、i686、noarch 這一類的 RPM, i386 RPM 幾乎可適用在所有 X86 電腦上,但 i686 RPM 就不一定可以適用在
386 或 586 電腦上。至於 noarch RPM 則是不分任何操作平台的。 |
至於像 SRPM 的套件檔案一般都取名為 xxx.src.rpm。
底下就開始來介紹如何管理 RPM 套件。這裡我們是要使用 rpm 指令來對套件進行查詢、安裝、升級、移除等動作:
※ 套件查詢
如果是查詢已安裝套件的相關資訊,則後面是接 package-name,否則需接 package-file。
| suselinux:~ #
rpm -q xinetd
xinetd-2.3.13-39.3
→
-q 同於 --query。查詢
xinetd 套件是否已安裝。
suselinux:~ # rpm -qa
→
-a 同於 --all。查詢目前系統上所有已安裝套件。
suselinux:~ # rpm -qa | grep openssh
openssh-3.8p1-37.9
openssh-askpass-3.8p1-37.9
→
查詢套件名稱中含有 openssh 這個 pattern
的所有套件。
suselinux:~ # rpm -ql xinetd
→
-l 同於 --list。查詢套件清單。
suselinux:~ # rpm -qi xinetd
→
-i 同於 --info。查詢套件資訊,如套件名稱、套件版本、套件大小、發行商、數位簽章及套件的簡單描述等等。
suselinux:~ # rpm -qR bind
→
-R 同於 --requires。查詢
bind 套件的相依性。
suselinux:~ # rpm -qf /etc/inittab
aaa_base-9-29.8
→
-f 同於 --file。查詢
/etc/inittab 這個檔案是屬於哪個套件。
suselinux:~ # rpm -qc openssh
→
-c 同於 --configfiles。只查詢套件內的相關組態檔。
suselinux:~ # rpm -qd openssh
→
-d 同於 --docfiles。只查詢套件內的相關說明文件檔。
suselinux:~ # rpm -qilp ncftp-3.1.7-40.1.i586.rpm
→
-p 同於 --package。當您所查詢的套件尚未安裝於本地端時,可加上
-p 參數來查詢,其後需接 package-file。
suselinux:~ # rpm -q --changelog openssh
→
查詢套件的改變紀錄。套件從第一次釋出開始,每次有所修正並釋放出
release 版本時,都會有紀錄。
|
※ 套件安裝
顧名思義就是將套件檔案 (package-file) 安裝於系統上,完成後在 RPM 資料庫就會有這個套件的紀錄。
待會兒練習時,可拿出您手邊的光碟來實作看看:
suselinux:~ # cd
/media/cdrom/suse/i586/
suselinux:~ /media/cdrom/suse/i586 # rpm -ivh
ncftp-3.1.7-40.1.i586.rpm
| Preparing... |
########################################### [100%] |
| 1:ncftp |
########################################### [100%] |
說明:
-i 同於 --install。安裝套件時的主要參數。
-v 同於 --verbose。顯示執行過程。
-h 同於 --hash。顯示安裝的進度,像上面那個
"#" 就是 -h 參數的效果。
suselinux:/media/cdrom/suse/i586 # rpm -ivh
apache2-2.0.49-27.8.i586.rpm
error: Failed dependencies:
apache2-MPM is needed by apache2-2.0.49-27.8
libapr0 = 2.0.49 is needed by apache2-2.0.49-27.8
libapr-0.so.0 is needed by apache2-2.0.49-27.8
libaprutil-0.so.0 is needed by apache2-2.0.49-27.8
| → |
由於
apache2 有套件相依性的問題,所以您無法安裝成功,而如果欲忽略套件相依性來安裝的話,可加上 --nodeps
參數: |
suselinux:/media/cdrom/suse/i586 # rpm -ivh
--nodeps apache2-2.0.49-27.8.i586.rpm
| Preparing... |
########################################### [100%] |
| 1:apache2 |
########################################### [100%] |
| → |
不考慮相依性來安裝
apache2 套件。這個範例只是給各位參考而已,平常在安裝套件時可千萬不要這麼做啊 ! 不然就算您強制安裝上去,可能將來也會出現不少問題噢。 |
另外當您套件已安裝在系統上,又想再安裝一次,或安裝時出現 [confilcting files] 訊息時,則可使用
--force 參數來強迫安裝:
suselinux:/media/cdrom/suse/i586 # rpm -ivh
--force ncftp-3.1.7-40.1.i586.rpm
| Preparing... |
########################################### [100%] |
| 1:ncftp |
########################################### [100%] |
| → |
--force 相當於
--replacepkgs、--replacefiles、
--oldpackage,至於這些參數的詳細用法,請 " man rpm "。不過還是老話一句,盡量勿使用。
|
|
※ 套件升級
在系統管理上,套件的升級是很重要的一環,因為套件推出後,可能過一陣子就會有一些 bug 出來,這時候您就得進行套件升級的動作,這樣對系統安全才會比較有保障。
套件升級常使用 " -Uvh " 或 "-Fvh "
參數,不過兩者是有差別的:
| -U |
同於 --upgrade。當系統已存在舊版本套件時,直接進行升級,但若不存在,則當成新安裝套件來安裝。如果存在的現有版本與升級版本相同,則會顯示套件已安裝的訊息。 |
| -F |
同於 --freshen。當系統已存在舊版本套件時,直接進行升級,但若不存在,則不會安裝。如果存在的現有版本與升級版本相同,也不會進行安裝。使用這個參數來將所有安裝過的套件進行全系統升級非常方便。
| suselinux:~ # rpm -Fvh *.rpm |
|
在 SuSE 裡頭您可以利用 YOU (YaST Online Update) 來做全系統的線上升級,不過如果您是使用 SLES,請先至官方網站建立一組帳號密碼,因為在升級前會要求您輸入登入帳號。接著請參考以下的操作步驟
(這個操作筆者是使用 professional 的版本,所以在升級過程將不會出現要求輸入帳號的訊息):

點選 [Online Update]。

選擇 [Reload All Patches from Server],這樣會自動幫您下載及安裝更新的套件。

取得更新的資訊。

這裡是詢問您是否要升級核心,如果願意的話,請點選 [Install Patch]。另外建議您核心升級後請 reboot,因為有些額外的核心模組在 reboot
後需要被載入。

開始下載及安裝更新的套件。

這裡只是提醒您如果 Boot Loader 是使用 LILO 的話,在更新完成後 reboot 前要執行 lilo。

更新套件安裝完畢後,接著 SuSEconfig 會幫您更新相關組態檔。

這樣就輕輕鬆鬆的完成線上升級了,簡單吧 !
※ 套件移除
suselinux:~ #
rpm -e ncftp
→ -e
同於 --erase。移除
ncftp 套件。
suselinux:~ # rpm -q ncftp
package ncftp is not installed
→ 瞧,資料庫裡頭已沒有 ncftp 的紀錄了。
安裝套件會有所謂相依性的問題,那移除套件當然也會有,如移除時想排除相依性的問題,可加上 --nodeps 參數。 |
※ 套件內容核對
如您想了解某個套件內有哪些檔案異動過,或者檢查尚未安裝套件的完整性,那麼就要學會以下的用法噢:
suselinux:~ #
rpm -V vsftpd
S.5 . . . . T c /etc/vsftpd.conf
| → |
-V
同於 --verify。核對套件內的哪些檔案做了哪些異動。至於前面出現的字元所代表意義如下:
| 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。
連結檔的連結路徑有修改過。 |
| U
: |
User ownership differs。
檔案的擁有者變更過。 |
| G
: |
Group ownership differs。
檔案的擁有群組變更過。 |
| T
: |
mTime differs。
檔案的修改時間異動過。 |
至於最後面那個小寫的
c (configuration file) 是代表組態檔的意思。
|
suselinux:~ # rpm -Va > verifyfile &
| → |
檢視系統所有已安裝套件中有異動過的檔案,並將結果輸出至
verifyfile。最後用了個背景執行的符號,因為這個檢查動作會花不少時間,所以為了不讓程式佔用前景終端機,就把它丟到背景執行囉
! |
在我們下載了新的套件之後,但尚未安裝之前,可以先使用 --checksig 參數來檢查套件的數位簽章,以驗證原始套件內容是否被修改過:
suselinux:~ # rpm --checksig ncftp-3.1.7-40.1.i586.rpm
ncftp-3.1.7-40.1.i586.rpm: sha1 md5 gpg OK
另外您也可以使用 md5sum 指令來做驗證,比如我們不是常常會到
FTP 站台抓取 ISO 檔嗎,那您如何確認這個 ISO 檔沒被其他人修改過呢,很簡單,只要將對方提供的 MD5SUMS 檔案下載回來後,查一下這個
ISO 檔的 md5 檢查碼,然後在本機執行:
suselinux:~ # md5sum SUSE-9.3-Eval-DVD.iso
04d2ebe4e0b8b00bc83cdc180a79e667
| → |
接著就比較執行的結果與 MD5SUMS 檔案所提供的檢查碼是否一致。 |
|
※ 重建 RPM 資料庫
由於在安裝、移除、升級套件或修改 RPM 套件內的檔案時,RPM 資料庫都必須做相關的紀錄,因此它可是非常的忙碌,所以時間一拉長,或許資料庫會顯得較無次序,此時您便可以考慮重整一下資料庫。另外有時候您安裝套件時,卻出現一些以前不曾遇過的錯誤訊息
(非相依性的問題),導致您無法正常安裝,這時候也可嘗試先重建 RPM 資料庫後再行安裝。最後就是當您執行全系統升級完畢後,馬上重建 RPM 資料庫也是個不錯的選擇。講了半天,那到底要怎麼做呢
? 很簡單的,請執行:
| suselinux:~ # rpm --rebuilddb |
7.3.3
編譯原始碼 RPM
當您使用原始碼 RPM 來進行安裝時,必須先對其進行編譯打包的動作,等產生了 binary RPM 以後才可以安裝上去。一般我們下載回來的 SRPM 都會存放在
/usr/src/packages 底下的 SRPMS 目錄中,而除了 SRPMS 目錄外,您還會看到與 SRPM 相關的目錄,先來解釋一下這些目錄的功用:
suselinux:~ # cd
/usr/src/packages/
suselinux:/usr/src/packages # ls
BUILD RPMS SOURCES SPECS SRPMS |
| SRPMS |
一般存放 Source RPM 的目錄。 |
| SOURCES |
執行安裝 SRPM 後,會在此目錄下產生該套件的原始碼檔案 (tarball)。 |
| BUILD |
編譯過程的暫存資料會放在這裡。 |
| SPECS |
執行安裝 SRPM 後,會產生一個 xx.spec 的設定參數檔案,這是在產生 RPM 套件檔案的過程裡面最重要的一個關鍵參數檔案。 |
| RPMS |
將編譯成功後的套件檔案,安置於其下的相關子目錄中。比如產生的是
i586 的 RPM 就放在 i586 目錄下。 |
範例說明:
先到網路上抓一個 SRPM 回來:ftp://ftp.isu.edu.tw/Linux/SuSE/i386/9.0/suse/src/ncftp-3.1.5-107.src.rpm
或者您光碟裡有 SRPM 的話,也可以直接拿來練習。然後將 SRPM 安置在 /usr/src/packages/SRPMS 中,並開始執行以下的步驟:
| suselinux:/usr/src/packages/SRPMS
# rpm -ivh ncftp-3.1.5-107.src.rpm
1:ncftp ########################################### [100%]
接著可瀏覽一下 SOURCES 及 SPECS
目錄的內容:
suselinux:/usr/src/packages # ls SOURCES/
ncftp-3.1.5-src.tar.bz2 ncftp-3.1.5.diff
| → |
產生了
ncftp 的 tarball。這是在等一下的編譯過程要用到的原始碼檔案。 |
suselinux:/usr/src/packages #
ls SPECS/
ncftp.spec
| → |
這是在編譯成
RPM 的過程裡所使用的設定參數檔。 |
suselinux:/usr/src/packages #
cd SPECS/
suselinux:/usr/src/packages/SPECS # rpmbuild
-ba ncftp.spec
suselinux:/usr/src/packages # ls
RPMS/i586/
ncftp-3.1.5-107.i586.rpm
|
請看另外一種直接產生 binary RPM 的方式:
|
suselinux:/usr/src/packages/SRPMS # rpmbuild
--rebuild ncftp-3.1.5-107.src.rpm
Installing ncftp-3.1.5-107.src.rpm
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.60771
drwxr-xr-x root/bin 0 2002-10-13 19:31:57 ncftp-3.1.5/
drwxr-xr-x root/bin 0 2002-10-13 19:31:57 ncftp-3.1.5/libncftp/
:
checking for ANSI C header files... yes
checking for arpa/nameser.h... yes
checking for gnu/libc-version.h... yes
checking for locale.h... yes
:
Compiling Strnpcat.c.
Compiling DStrCpy.c.
Compiling DStrNew.c.
→ 這樣就會直接在 /usr/src/packages/RPMS/i586/
中產生 binary RPM 了。
|
或許各位會覺得說使用第二種方式來直接產生 RPM 比較快啊,那第一種方式什麼時候用得到呢 ? 其實如果您懂得 RPM
原理的話,採用第一種方式當然是比較具有彈性的,它的好處有:
1. 可以手動來調整設定參數。
2. 可以修改原始碼內容。
3. 可以替換套件中的部分檔案。
當然如果您都不想做調整的話,那就使用第二種方式即可 !
其實我們也可以使用 rpm 指令來直接進行編譯,不過您需要先去編輯 /etc/popt 檔案:
suselinux:~ # vi
/etc/popt
rpm exec --rebuild rpmb --rebuild
rpm exec --ba rpmb -ba |
這樣您就可以使用 "rpm --rebuild xx.src.rpm"、"rpm
-ba xx.spec" 來執行工作噢。
7.4
動態連結資料庫 ( Dynamic Link Library ):DLL
在 Linux 系統上所執行的程式都會使用到函式庫,而依照應用程式與函式庫連結的方式可區分為靜態函式庫 (Static Libraries) 及動態函式庫
(Dynamic Libraries、Shared Libraries) ,這兩者其實是很好區別的。靜態函式庫 (通常為 xx.a) 裡的函式原始碼需要被編譯到主程式裡頭,所以主程式會顯得比較臃腫些,但好處是該程式可以獨立執行
; 動態函式庫 (通常為 xx.so,如您看到的是 xx.so.2.1 之類的,那個 2.1 就是版本囉 ) 則不需整個被編譯到主程式裡邊,只需在程式的原始碼裡設計去呼叫動態函式庫即可。在
Linux 中所執行的程式幾乎都是使用動態連結資料庫。
一般傳統的函式庫是安置在 /lib 及 /usr/lib 目錄中,而提供系統來搜尋的函式庫所放置的目錄是定義在
/etc/ld.so.conf 裡。當執行 ldconfig 指令時,會先去讀取 /etc/ld.so.conf,以找出函式庫所放置的目錄位置,然後才能將這些函式庫資料寫入
cache 內,並存放一份在 /etc/ld.so.cache 中。而我們在執行一支程式時,就會由
ld.so 這個動態連結器 (dynamic linker) 程式到 cache 內去尋找執行程式所需的函式,以提供程式做動態連結。不過您要是看過
/etc/ld.so.conf 會發現 /lib 及 /usr/lib 並沒有定義在 ld.so.conf 內,因為這兩個目錄是內定值,所以不需要做設定啦
! 最後如果您有設定 LD_LIBRARY_PATH 這個環境變數的話,其所定義的目錄也會被讀入。
如果哪天您函式庫所存放的目錄有所異動,請記得修改 /etc/ld.so.conf,然後再執行 ldconfig 指令,這樣才可以更新 cache 內的資料。
以下我們稍作整理:
| 1. |
DLL 一般是安置在 /lib 或 /usr/lib 目錄下,而除了這兩個目錄外,DLL 所存放的目錄必須在 /etc/ld.so.conf
或 LD_LIBRARY_PATH 中做定義。 |
| 2. |
執行指令 ldconfig 時,會先去讀取 /etc/ld.so.conf,然後將 DLL 讀入 cache,並紀錄一份在 /etc/ld.so.cache
; 當執行程式在執行時,ld.so 就會根據 cache 來找出並載入程式所需的函式庫,以讓程式能正確的執行。 |
| 3. |
欲瀏覽 /etc/ld.so.cache 內的資料,可執行:
| suselinux:~ # ldconfig -p |
|
| 4. |
現在如果新增一些 DLL於某個目錄內,您必須將此目錄設定在 /etc/ld.so.conf,接著執行 ldconfig 來更新 cache
的資料。 |
| 5. |
增加、減少、刪除部份 DLL 或 DLL 目錄有異動,就須執行 ldconfig。 |
| 6. |
系統於開機時,預設就會執行 ldconfig,以確保 cache 內的資料是最新的。 |
至於要查詢所執行的程式使用了哪些 DLL,則執行 ldd 指令即可:
suselinux:~ # which
fdisk rpm
/sbin/fdisk
/bin/rpm
suselinux:~ # ldd /sbin/fdisk /bin/rpm
/sbin/fdisk:
linux-gate.so.1 => (0xffffe000)
libc.so.6 => /lib/tls/libc.so.6 (0x40025000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
/bin/rpm:
linux-gate.so.1 => (0xffffe000)
librpmbuild-4.1.so => /usr/lib/librpmbuild-4.1.so (0x40025000)
librpm-4.1.so => /usr/lib/librpm-4.1.so (0x40057000)
librpmdb-4.1.so => /usr/lib/librpmdb-4.1.so (0x400a5000)
librpmio-4.1.so => /usr/lib/librpmio-4.1.so (0x40185000)
libpopt.so.0 => /usr/lib/libpopt.so.0 (0x401d4000)
librt.so.1 => /lib/tls/librt.so.1 (0x401dd000)
libpthread.so.0 => /lib/tls/libpthread.so.0 (0x401e5000)
libz.so.1 => /lib/libz.so.1 (0x401f5000)
libbz2.so.1 => /usr/lib/libbz2.so.1 (0x40206000)
libc.so.6 => /lib/tls/libc.so.6 (0x40216000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000) |
copyright © 2005 by barry ( 柏青哥
)