本文已不再維護,更新文章請參考此處
在 Linux 底下有相當多的壓縮指令可以運作喔!這些壓縮指令可以讓我們更方便從網路上面下載大型的檔案呢! 此外,我們知道在 Linux 底下的副檔名是沒有什麼很特殊的意義的,不過,針對這些壓縮指令所做出來的壓縮檔, 為了方便記憶,還是會有一些特殊的命名方式啦!就讓我們來看看吧!

1. 壓縮檔案的用途與技術:
2. Linux 系統常見的壓縮指令:
  2.1 compress
  2.2 gzip, zcat
  2.3 bzip2, bzcat
  2.4 tar
  2.5 dd
  2.6 cpio
3. 本章習題練習
4. 針對本文的建議:http://phorum.vbird.org/viewtopic.php?t=23882

壓縮檔案的用途與技術:
您是否有過文件檔案太大,導致無法以一片軟碟將他複製完成的困擾? 又,您是否有過,發現一個軟體裡面有好多檔案,這些檔案要將他複製與攜帶都很不方便的問題? 還有,您是否有過要備份某些重要資料,偏偏這些資料量太大了,耗掉了你很多的硬碟與磁碟空間呢? 這個時候,那個好用的『檔案壓縮』技術可就派的上用場了! 因為這些比較大型的檔案透過所謂的檔案壓縮技術之後,可以將他的磁碟使用量降低, 可以達到減低檔案容量的效果,此外,有的壓縮程式還可以進行容量限制, 使一個大型檔案可以分割成為數個小型檔案,以方便軟碟片攜帶呢!

那麼什麼是『檔案壓縮』呢?我們來稍微談一談他的原理好了。目前我們使用的電腦系統中都是使用所謂的 bytes 單位來計量的!不過,事實上,電腦最小的計量單位應該是 bits 才對啊,此外,我們也知道 1 byte = 8 bits 。但是如果今天我們只是記憶一個數字,亦即是 1 這個數字呢?他會如何記錄?假設一個 byte 可以看成底下的模樣: 由於 1 byte = 8 bits ,所以每個 byte 當中會有 8 個空格,而每個空格可以是 0, 1 ,這裡僅是做為一個約略的介紹,讀者不必刻意記憶。 而由於我們記錄數字是 1 ,考慮電腦所謂的二進位喔,如此一來, 1 會在最右邊佔據 1 個 bit ,而其他的 7 個 bits 將會自動的被填上 0 囉!你看看,其實在這樣的例子中,那 7 個 bits 應該是『空的』才對!不過,為了要滿足目前我們的作業系統資料的存取,所以就會將該資料轉為 byte 的型態來記錄了!而一些聰明的電腦工程師就利用一些複雜的計算方式, 將這些沒有使用到的空間『丟』出來,以讓檔案佔用的空間變小!這就是壓縮的技術啦!

簡單的說,你可以將他想成,其實檔案裡面有相當多的『空間』存在,並不是完全填滿的, 而『壓縮』的技術就是將這些『空間』填滿,以讓整個檔案佔用的容量下降! 不過,這些『壓縮過的檔案』並無法直接被我們的作業系統所使用的,因此, 若要使用這些被壓縮過的檔案資料,則必須將他『還原』回來未壓縮前的模樣, 那就是所謂的『解壓縮』囉!而至於壓縮前與壓縮後的檔案所佔用的磁碟空間大小, 就可以被稱為是『壓縮比』囉!更多的技術文件或許你可以參考一下: 這個『壓縮』與『解壓縮』的動作有什麼好處呢?最大的好處就是壓縮過的檔案容量變小了, 所以你的硬碟容量無形之中就可以容納更多的資料,此外,在一些網路資料的傳輸中,也會由於資料量的降低, 好讓網路頻寬可以用來作更多的工作!而不是老是卡在一些大型的檔案上面呢!目前很多的 WWW 網站也是利用檔案壓縮的技術來進行資料的傳送,好讓網站的可利用率上升喔!
這種技術蠻有趣的!他讓您網站上面『看的到的資料』在經過網路傳輸時,使用的是『壓縮過的資料』, 等到這些壓縮過的資料到達你的電腦主機時,再進行解壓縮,由於目前的電腦運算速度相當的快速, 因此其實在網頁瀏覽的時候,時間都是花在『資料的傳輸』上面,而不是 CPU 的運算啦!,如此一來,由於壓縮過的資料量降低了,自然傳送的速度就會增快不少! 若您是一位軟體工程師,那麼相信您也會喜歡將你自己的軟體壓縮之後提供大家下載來使用, 畢竟沒有人喜歡自己的網站天天都是頻寬滿載的吧?!舉個例子來說, Linux 2.4.19 完整的核心大小約有 200 MB 左右,而由於核心主要多是 ASCII code 的純文字型態檔案,這種檔案的『多餘空間』最多了。而一個提供下載的壓縮過的 2.4.19 核心大約僅有 30MB 左右,差了幾倍呢?您可以自己算一算喔!

Linux 系統常見的壓縮指令:
如果您常常在網路上面捉 Linux 的資料下來玩的話,大概會曉得的是,這些供人下載的檔案通常都是『壓縮』過的! 為了什麼?上面已經稍微提過啦!呵呵!壓縮過的檔案具有節省頻寬、節省磁碟空間等等的優點,並且還方便攜帶呢! ^_^ !而,您應該也會知道,這些被壓縮過的檔案,通常其副檔名都是『 *.tar, *.tar.gz, *.tgz, *.gz, *.Z, *.bz2 』 等等的,為什麼要訂定這些壓縮檔案副檔名為這樣的模樣呢?

這是因為在 Linux 上面壓縮的指令相當的多,並且,這些壓縮指令可能無法針對每種壓縮檔案都可以解的開, 畢竟目前的壓縮技術五花八門,每種壓縮計算的方法都不是完全相同的,所以囉,當你捉到某個壓縮檔時, 自然就需要知道壓縮他的是那個指令啦,好用來對照著解壓縮啊! ^_^!也就是說,雖然 Linux 檔案的屬性基本上是與檔名沒有絕對關係的,能不能執行與他的檔案屬性有關而已, 與檔名的關係很小!但是,為了幫助我們小小的人類腦袋瓜子,所以適當的檔案名稱副檔名還是必要的! 因此,目前就有一些常常見到的壓縮檔案的副檔名啦!我們僅列出常見的幾樣在底下,給大家權做參考之用: 目前常見的壓縮程式主要就是如同上面提到的副檔名對應的那些指令啦!最早期的要算是 compress 這個傢伙了,不過這個 compress 指令目前已經不再是預設的壓縮軟體了∼ 而後,後來的 GNU 計畫開發出新一代的壓縮指令 gzip ( GNU zip ) 用來取代 compress 這個老牌的壓縮指令,再來還有 bzip2 這個壓縮比更好的壓縮指令呢!不過,這些指令通常僅能針對一個檔案來壓縮與解壓縮,如此一來, 每次壓縮與解壓縮都要一大堆檔案,豈不煩人?此時,那個所謂的『打包軟體』就顯的很重要啦!

在 Unix-Like 當中,有個軟體很好玩,他就是 tar 這支程式!這個 tar 可以將很多檔案『打包』成為一個檔案! 甚至是目錄也可以這麼玩。不過,單純的 tar 功能僅是『打包』而已,亦即是將很多檔案集結成為一個檔案,事實上,他並沒有提供壓縮的功能,後來, GNU 計畫中,將整個 tar 與壓縮的功能結合在一起,如此一來提供使用者更方便並且更強大的壓縮與打包功能! 底下我們就來談一談這些在 Linux 底下基本的壓縮指令吧!


compress
[root@linux ~]# compress [-dcr] 檔案或目錄
參數:
-d  :用來解壓縮的參數
-r  :可以連同目錄下的檔案也同時給予壓縮呢!
-c  :將壓縮資料輸出成為 standard output (輸出到螢幕)
範例:
範例一:將 /etc/man.config 複製到 /tmp ,並加以壓縮
[root@linux ~]# cd /tmp
[root@linux tmp]# cp /etc/man.config .
[root@linux tmp]# compress man.config
[root@linux tmp]# ls -l
-rw-r--r--  1 root root 2605 Jul 27 11:43 man.config.Z

範例二:將剛剛的壓縮檔解開
[root@linux tmp]# compress -d man.config.Z

範例三:將 man.config 壓縮成另外一個檔案來備份
[root@linux tmp]# compress -c man.config > man.config.back.Z
[root@linux tmp]# ll man.config*
-rw-r--r--  1 root root 4506 Jul 27 11:43 man.config
-rw-r--r--  1 root root 2605 Jul 27 11:46 man.config.back.Z
# 這個 -c 的參數比較有趣!他會將壓縮過程的資料輸出到螢幕上,而不是寫入成為 
# file.Z 檔案。所以,我們可以透過資料流重導向的方法將資料輸出成為另一個檔名。
# 關於資料流重導向,我們會在 bash shell 當中詳細談論的啦!
這是用來壓縮與解壓縮副檔名為 *.Z 的指令!所以看到 *.Z 的檔案時,就應該要知道他是經由 compress 這個程式壓縮的呦!這是最簡單的壓縮指令囉!不過,使用的時候需要特別留意的是, 當你以 compress 壓縮之後,如果沒有下達其他的參數,那麼原本的檔案就會被後來的 *.Z 所取代!以上面的案例來說明:原本壓縮的檔案為 man.config ,那麼當壓縮完成之後,將只會剩下 man.config.Z 這個經過壓縮的檔案囉!那麼解壓縮呢?呵呵,則是將 man.config.Z 解壓縮成 man.config ! 使用上很簡單啦!解壓縮除了可以使用 compress –d 這個參數之外,也可以直接使用 uncompress !意思相同啦!

另外,如果不想讓原本的檔案被更名成為 *.Z ,而想製作出另外的一個檔名時,就可以利用資料流重導向, 亦即是那個大於 (>) 的符號,將原本應該在螢幕上面出現的資料給他儲存到其他檔案去。 當然,這要加上 -c 的參數才行∼關於資料流重導向,我們會在第三篇提到的!此外, compress 已經很少人在使用了, 因為這支程式無法解開 *.gz 的檔案,而 gzip 則可以解決 *.Z 的檔案, 所以,如果您的 distribution 上面沒有 compress 的話,沒有關係的喔!
compress 使用的頻率越來越低了,如果您還是想要練習這個指令的話, 在 FC4 裡頭,他是在 ucompress 這個套件名稱的套件內。您可以參考 RPM 的方式來安裝!

gzip, zcat
[root@linux ~]# gzip [-cdt#] 檔名
[root@linux ~]# zcat 檔名.gz
參數:
-c  :將壓縮的資料輸出到螢幕上,可透過資料流重導向來處理;
-d  :解壓縮的參數;
-t  :可以用來檢驗一個壓縮檔的一致性∼看看檔案有無錯誤;
-#  :壓縮等級,-1 最快,但是壓縮比最差、-9 最慢,但是壓縮比最好!預設是 -6 ∼
範例:
範例一:將 /etc/man.config 複製到 /tmp ,並且以 gzip 壓縮
[root@linux ~]# cd /tmp 
[root@linux tmp]# cp /etc/man.config . 
[root@linux tmp]# gzip man.config 
# 此時 man.config 會變成 man.config.gz !

範例二:將範例一的檔案內容讀出來!
[root@linux tmp]# zcat man.config.gz
# 此時螢幕上會顯示 man.config.gz 解壓縮之後的檔案內容!!

範例三:將範例一的檔案解壓縮
[root@linux tmp]# gzip -d man.config.gz

範例四:將範例三解開的 man.config 用最佳的壓縮比壓縮,並保留原本的檔案
[root@linux tmp]# gzip -9 -c man.config > man.config.gz
gzip 是用來壓縮與解壓縮副檔名為 *.gz 的指令!所以看到 *.gz 的檔案時,就應該要知道他是經由 gzip 這個程式壓縮的呦!另外, gzip 也提供 壓縮比的服務! -1 是最差的壓縮比,但是壓縮速度最快,而 -9 雖然可以達到較佳的壓縮比 (經過壓縮之後,檔案比較小一些!) ,但是卻會損失一些速度!預設是 -6 這個數值! gzip 也是相當常使用的一個壓縮指令呢!

至於 zcat 則是用來讀取壓縮檔資料內容的指令!假如我們剛剛壓縮的檔案是一個文字檔, 那麼你還記得如何讀取文字檔嗎?!沒錯!就是使用 cat ,那麼讀取壓縮檔呢?呵呵!就是使用 zcat 囉!由於 gzip 這個壓縮指令主要想要用來取代 compress 的,所以 compress 的壓縮檔案也可以使用 gzip 來解開喔!同時, zcat 這個指令可以同時讀取 compress 與 gzip 的壓縮檔呦!


bzip2, bzcat
[root@linux ~]# bzip2 [-cdz] 檔名
[root@linux ~]# bzcat 檔名.bz2
參數:
-c  :將壓縮的過程產生的資料輸出到螢幕上!
-d  :解壓縮的參數
-z  :壓縮的參數
-#  :與 gzip 同樣的,都是在計算壓縮比的參數, -9 最佳, -1 最快!
範例:
範例一:將剛剛的 /tmp/man.config 以 bzip2 壓縮
[root@linux tmp]# bzip2 -z man.config 
# 此時 man.config 會變成 man.config.bz2 !

範例二:將範例一的檔案內容讀出來!
[root@linux tmp]# bzcat man.config.bz2
# 此時螢幕上會顯示 man.config.bz2 解壓縮之後的檔案內容!!

範例三:將範例一的檔案解壓縮
[root@linux tmp]# bzip2 -d man.config.bz2

範例四:將範例三解開的 man.config 用最佳的壓縮比壓縮,並保留原本的檔案
[root@linux tmp]# bzip2 -9 -c man.config > man.config.bz2
使用 compress 副檔名自動建立為 .Z ,使用 gzip 副檔名自動建立為 .gz 。這裡的 bzip2 則是自動的將副檔名建置為 .bz2 囉!所以當我們使用具有壓縮功能的 bzip2 -z 時,那麼剛剛的 man.config 就會自動的變成了 man.config.bz2 這個檔名囉!

好了,那麼如果我想要讀取這個檔案的內容呢? 是否一定要解開?當然不需要囉!可以使用簡便的 bzcat 這個指令來讀取內容即可!例如上面的例子中, 我們可以使用 bzcat man.config.bz2 來讀取資料而不需要解開!此外,當您要解開一個壓縮檔時, 這個檔案的名稱為 .bz, .bz2, .tbz, .tbz2 等等,那麼就可以嘗試使用 bzip2 來解看看啦!當然囉,也可以使用 bunzip2 這個指令來取代 bzip2 -d 囉。


tar
[root@linux ~]# tar [-cxtzjvfpPN] 檔案與目錄 ....
參數:
-c  :建立一個壓縮檔案的參數指令(create 的意思);
-x  :解開一個壓縮檔案的參數指令! 
-t  :查看 tarfile 裡面的檔案!
      特別注意,在參數的下達中, c/x/t 僅能存在一個!不可同時存在!
      因為不可能同時壓縮與解壓縮。
-z  :是否同時具有 gzip 的屬性?亦即是否需要用 gzip 壓縮?
-j  :是否同時具有 bzip2 的屬性?亦即是否需要用 bzip2 壓縮?
-v  :壓縮的過程中顯示檔案!這個常用,但不建議用在背景執行過程!
-f  :使用檔名,請留意,在 f 之後要立即接檔名喔!不要再加參數!
   例如使用『 tar -zcvfP tfile sfile』就是錯誤的寫法,要寫成
   『 tar -zcvPf tfile sfile』才對喔!
-p  :使用原檔案的原來屬性(屬性不會依據使用者而變) 
-P  :可以使用絕對路徑來壓縮!
-N  :比後面接的日期(yyyy/mm/dd)還要新的才會被打包進新建的檔案中! 
--exclude FILE:在壓縮的過程中,不要將 FILE 打包! 
範例:
範例一:將整個 /etc 目錄下的檔案全部打包成為 /tmp/etc.tar 
[root@linux ~]# tar -cvf /tmp/etc.tar /etc  <==僅打包,不壓縮!
[root@linux ~]# tar -zcvf /tmp/etc.tar.gz /etc  <==打包後,以 gzip 壓縮
[root@linux ~]# tar -jcvf /tmp/etc.tar.bz2 /etc  <==打包後,以 bzip2 壓縮
# 特別注意,在參數 f 之後的檔案檔名是自己取的,我們習慣上都用 .tar 來作為辨識。
# 如果加 z 參數,則以 .tar.gz 或 .tgz 來代表 gzip 壓縮過的 tar file ∼
# 如果加 j 參數,則以 .tar.bz2 來作為副檔名啊∼
# 上述指令在執行的時候,會顯示一個警告訊息:
# 『tar: Removing leading `/' from member names』那是關於絕對路徑的特殊設定。

範例二:查閱上述 /tmp/etc.tar.gz 檔案內有哪些檔案?
[root@linux ~]# tar -ztvf /tmp/etc.tar.gz 
# 由於我們使用 gzip 壓縮,所以要查閱該 tar file 內的檔案時,
# 就得要加上 z 這個參數了!這很重要的!

範例三:將 /tmp/etc.tar.gz 檔案解壓縮在 /usr/local/src 底下
[root@linux ~]# cd /usr/local/src
[root@linux src]# tar -zxvf /tmp/etc.tar.gz
# 在預設的情況下,我們可以將壓縮檔在任何地方解開的!以這個範例來說,
# 我先將工作目錄變換到 /usr/local/src 底下,並且解開 /tmp/etc.tar.gz ,
# 則解開的目錄會在 /usr/local/src/etc 呢!另外,如果您進入 /usr/local/src/etc
# 則會發現,該目錄下的檔案屬性與 /etc/ 可能會有所不同喔!

範例四:在 /tmp 底下,我只想要將 /tmp/etc.tar.gz 內的 etc/passwd 解開而已
[root@linux ~]# cd /tmp
[root@linux tmp]# tar -zxvf /tmp/etc.tar.gz etc/passwd
# 我可以透過 tar -ztvf 來查閱 tarfile 內的檔案名稱,如果單只要一個檔案,
# 就可以透過這個方式來下達!注意到! etc.tar.gz 內的根目錄 / 是被拿掉了!

範例五:將 /etc/ 內的所有檔案備份下來,並且保存其權限!
[root@linux ~]# tar -zcvpf /tmp/etc.tar.gz /etc
# 這個 -p 的屬性是很重要的,尤其是當您要保留原本檔案的屬性時!

範例六:在 /home 當中,比 2005/06/01 新的檔案才備份
[root@linux ~]# tar -N '2005/06/01' -zcvf home.tar.gz /home

範例七:我要備份 /home, /etc ,但不要 /home/dmtsai 
[root@linux ~]# tar --exclude /home/dmtsai -zcvf myfile.tar.gz /home/* /etc

範例八:將 /etc/ 打包後直接解開在 /tmp 底下,而不產生檔案! 
[root@linux ~]# cd /tmp
[root@linux tmp]# tar -cvf - /etc | tar -xvf -
# 這個動作有點像是 cp -r /etc /tmp 啦∼依舊是有其有用途的!
# 要注意的地方在於輸出檔變成 - 而輸入檔也變成 - ,又有一個 | 存在∼
# 這分別代表 standard output, standard input 與管線命令啦!
# 這部分我們會在 Bash shell 時,再次提到這個指令跟大家再解釋囉!
這是一個多用途的壓縮指令!剛剛我們提到的 compress 與 gzip 是可以適用在一個檔案的壓縮上面, 但是如果是要將一個目錄壓縮成一個檔案呢?!這時該如何是好?!呵呵! tar 就派上用場了! tar 可以將整個目錄或者是指定的檔案都整合成一個檔案!例如上面的範例一,他可以將 /etc 底下的檔案全部整合成一個檔案!同時, tar 可以配合 gzip (這個 gzip 的功能已經已經附加上 tar 裡面去了) ,同時整合並壓縮!呵呵!很方便吧!

tar 用來作備份是很重要的指令! 』而由於 tar 整合過後的檔案我們通常會取名為 *.tar ,而如果還含有 gzip 的壓縮屬性,那麼就取名為 *.tar.gz 囉!取這個檔名只是為了方便我們記憶這個檔案是什麼屬性罷了!並沒有實際的意義在!

 
  • 絕對路徑與權限的問題
  • 另外,需要注意的是,在使用的參數方面,有還有幾個有用的參數需要來瞭解一番,亦即是 -p 與 -P 這兩個!在我們的範例一當中,有提到一個警告訊息,那就是『 tar: Removing leading `/' from member names』 意思是說, tar 將 /etc 目錄的那個 / 拿掉了!這是因為擔心未來你在解開壓縮的時候,會產生一些困擾, 因為在 tar 裡面的檔案如果是具有『絕對路徑』的話,那麼你解開的檔案將會『一定』在該路徑下也就是 /etc,而不是相對路徑 (這裡請用心的想一想!) 。

    這樣子的最大困擾是,萬一有人拿走了你的這個檔案,並且將該檔案在他的系統上面解開!萬一他的系統上面正巧也有 /etc 這個目錄 (那當然是一定有的啊!),哈哈!他的檔案就會『正巧』被覆蓋了! 所以囉,在預設的情況中,如果是以『絕對路徑』來建立打包檔案,那麼 tar 將會自動的將 / 拿掉!這是為了剛剛說明的『安全』為前提所做的預設值。好了!但是你就是要以絕對路徑來建立打包的檔案!那麼就加入 -P 這個參數吧 (請注意!是大寫字元) !這樣就可以啦!

    那麼 -p 是什麼 (小寫字元) ?呵呵!那個 -p 是 permission 的意思,也就是『權限』啦!使用 -p 之後,被打包的檔案將不會依據使用者的身份來改變權限喔!

  • 關於檔案的更新日期:
  • 這裡還有一個值得注意的參數呦!那就是在備份的情況中很常使用的 -N 的這個參數! 你可以參考一下上面的例子就可以知道啦!在這個例子當中,相當重要的就是那個日期啦! 在備份的情況當中,我們都希望只要備份較新的檔案就好了,為什麼呢?因為舊的檔案我們已經有備份囉! 幹嘛還要再備份一次,浪費時間也浪費系統資源!這個時候此一參數就顯的相當的重要了啊!

  • 關於 standard input/standard output:
  • 在上面的例子中,最後一個例子很有趣『tar cvf - /etc | tar -xvf - 』!他是直接以管線命令『 pipe 』來進行壓縮、解壓縮的過程!在上面的例子中,我們想要『將 /etc 底下的資料直接 copy 到目前所在的路徑,也就是 /tmp 底下來』,但是又覺得使用 cp -r 有點麻煩,那麼就直接以這個打包的方式來打包,其中,指令裡面的 - 就是表示那個被打包的檔案啦!由於我們不想要讓中間檔案存在,所以就以這一個方式來進行複製的行為啦!

  • 什麼是 tarfile 與 tarball?
  • tar 的功能相當的多,而由於他是經由『打包』之後再處理的一個過程,所以常常我們會聽到 tarball 的檔案,那就是經由 tar 打包再壓縮的檔案啦! 而如果僅是打包而沒有壓縮的話,我們就稱為 tarfile 囉∼此外, tar 也可以用在備份的儲存媒體上面,最常見的就是磁帶機了!假設我的磁帶機代號為 /dev/st0 ,那麼我要將我的 /home 底下的資料都給他備份上去時,就是使用 tar /dev/st0 /home 就可以啦!很不錯吧!

    在 Linux 當中, gzip 已經被整合在 tar 裡面了!但是 Sun 或者其他較舊的 Unix 版本中, 當中的 tar 並沒有整合 gzip ,所以如果你需要解壓縮的話,就需要這麼做: 第一個步驟會將檔案解壓縮,第二個步驟才是將資料解出來!與其他壓縮程式不太一樣的是, bzip2, gzip 與 compress 在沒有加入特殊參數的時候,原先的檔案會被取代掉,但是使用 tar 則原來的與後來的檔案都會存在呦!


    dd
    我們在上一章當中,在製作出 swap file 時,使用過 dd 這個指令對吧?! 不過,這個指令可不只是製作一個檔案而已喔∼這個 dd 指令最大的功效,鳥哥認為,應該是在於『備份』啊! 因為 dd 可以讀取裝置的內容,然後將整個裝置備份成一個檔案呢!真的是相當的好用啊∼ dd 的用途有很多啦∼但是我們僅講一些比較重要的參數,如下:
    [root@linux ~]# dd if="input_file" of="output_file" bs="block_size" \
    count="number"
    參數:
    if   :就是 input file 囉∼也可以是裝置喔!
    of   :就是 output file 喔∼也可以是裝置;
    bs   :規劃的一個 block 的大小,如果沒有設定時,預設是 512 bytes
    count:多少個 bs 的意思。
    範例:
    
    範例一:將 /etc/passwd 備份到 /tmp/passwd.back 當中
    [root@linux ~]# dd if=/etc/passwd of=/tmp/passwd.back
    3+1 records in
    3+1 records out
    [root@linux ~]# ll /etc/passwd /tmp/passwd.back
    -rw-r--r--  1 root root 1746 Aug 25 14:16 /etc/passwd
    -rw-r--r--  1 root root 1746 Aug 29 16:57 /tmp/passwd.back
    # 仔細的看一下,我的 /etc/passwd 檔案大小為 1746 bytes,因為我沒有設定 bs ,
    # 所以預設是 512 bytes 為一個單位,因此,上面那個 3+1 表示有 3 個完整的 
    # 512 bytes,以及未滿 512 bytes 的另一個 block 的意思啦!
    # 事實上,感覺好像是 cp 這個指令啦∼
    
    範例二:備份 /dev/hda 的 MBR 
    [root@linux ~]# dd if=/dev/hda of=/tmp/mbr.back bs=512 count=1
    1+0 records in
    1+0 records out
    # 這就得好好瞭解一下囉∼我們知道整顆硬碟的 MBR 為 512 bytes,
    # 就是放在硬碟的第一個 sector 啦,因此,我可以利用這個方式來將
    # MBR 內的所有資料都紀錄下來,真的很厲害吧! ^_^
    
    範例三:將整個 /dev/hda1 partition 備份下來。
    [root@linux ~]# dd if=/dev/hda1 of=/some/path/filename
    # 這個指令很厲害啊!將整個 partition 的內容全部備份下來∼
    # 後面接的 of 必須要不是在 /dev/hda1 的目錄內啊∼否則,怎麼讀也讀不完∼
    # 這個動作是很有效用的,如果改天你必須要完整的將整個 partition 的內容填回去,
    # 則可以利用 dd if=/some/file of=/dev/hda1 來將資料寫入到硬碟當中。
    # 如果想要整個硬碟備份的話,就類似 Norton 的 ghost 軟體一般,
    # 由 disk 到 disk ,嘿嘿∼利用 dd 就可以啦∼厲害厲害!
    
    你可以說, tar 可以用來備份關鍵資料,而 dd 則可以用來備份整顆 partition 或 整顆 disk ,很不錯啊∼不過,如果要將資料填回到 filesystem 當中, 可能需要考慮到原本的 filesystem 才能成功啊!


    cpio
    這個指令可有趣了!他是透過資料流重導向的方法來將檔案進行輸出/輸入的一個方式∼ 因為我們尚未提到資料流重導向,所以,您可以先略過這的指令的練習。等到後續的章節讀完後, 再來這個章節瞧一瞧!
    [root@linux ~]# cpio -covB  > [file|device] <==備份
    [root@linux ~]# cpio -icduv < [file|device] <==還原
    參數:
    -o :將資料 copy 輸出到檔案或裝置上 
    -i :將資料自檔案或裝置 copy 出來系統當中 
    -t :查看 cpio 建立的檔案或裝置的內容 
    -c :一種較新的 portable format 方式儲存 
    -v :讓儲存的過程中檔案名稱可以在螢幕上顯示 
    -B :讓預設的 Blocks 可以增加至 5120 bytes ,預設是 512 bytes ! 
       這樣的好處是可以讓大檔案的儲存速度加快(請參考 i-nodes 的觀念) 
    -d :自動建立目錄!由於 cpio 的內容可能不是在同一個目錄內,
         如此的話在反備份的過程會有問題! 這個時候加上 -d 的話,
         就可以自動的將需要的目錄建立起來了! 
    -u :自動的將較新的檔案覆蓋較舊的檔案!
    範例:
    範例一:將所有系統上的資料通通寫入磁帶機內!
    [root@linux ~]# find / -print | cpio -covB > /dev/st0
    # 一般來說,使用 SCSI 介面的磁帶機,代號是 /dev/st0 喔!
    
    範例二:檢查磁帶機上面有什麼檔案?
    [root@linux ~]# cpio -icdvt < /dev/st0
    [root@linux ~]# cpio -icdvt < /dev/st0 > /tmp/content
    # 第一個動作當中,會將磁帶機內的檔名列出到螢幕上面,而我們可以透過第二個動作,
    # 將所有的檔名通通紀錄到 /tmp/content 檔案去!
    
    範例三:將磁帶上的資料還原回來∼
    [root@linux ~]# cpio -icduv < /dev/st0
    # 一般來說,使用 SCSI 介面的磁帶機,代號是 /dev/st0 喔!
    
    範例四:將 /etc 底下的所有『檔案』都備份到 /root/etc.cpio 中!
    [root@linux ~]# find /etc -type f | cpio -o > /root/etc.cpio
    # 這樣就能夠備份囉∼您也可以將資料以 cpio -i < /root/etc.cpio 
    # 來將資料捉出來!!!!
    
    這個 cpio 還蠻神奇的呢!他最適用於備份的時候使用的一個指令了!為什麼呢?因為他並不像 cp 一樣,可以直接的將檔案給他 copy 過去,例如 cp * /tmp 就可以將所在目錄的所有檔案 copy 到 /tmp 底下,在 cpio 這個指令的用法中,由於 cpio 無法直接讀取檔案, 而是需要『每一個檔案或目錄的路徑連同檔名一起』才可以被記錄下來!因此, cpio 最常跟 find 這個指令一起使用了!

    這個 cpio 好像不怎麼好用呦!但是,嘿嘿!他可是備份的時候的一項利器呢!因為他可以備份任何的檔案, 包括 /dev 底下的任何裝置檔案!呵呵!所以他可是相當重要的呢!!您說是吧! 而由於 cpio 必需要配合其他的程式,例如 find 來建立檔名,所以, cpio 與管線命令及資料流重導向的相關性就相當的重要了!


    本章習題練習
    (要看答案請將滑鼠移動到『答:』底下的空白處,按下左鍵圈選空白處即可察看)

    2003/02/09:第一次完成
    2003/05/05:修改 tar 的部分內容,尤其是 -P 這個參數的配合用法
    2005/07/26:將舊有的文章移動到 這裡
    2005/07/27:大略修改了一些風格,另外,動作較大的是在範例的部分!
    2005/08/29:加入了 dd 這個有趣的指令喔!
    2006/05/02:將原本『tar -zxvpf /tmp/etc.tar.gz /etc』修改為『tar -zcvpf /tmp/etc.tar.gz /etc』 感謝討論區網友 chinu 提供的資訊。