鍍金池/ 教程/ Linux/ 歸檔和備份
網絡系統(tǒng)
打印
重定向
使用命令
位置參數(shù)
權限
文本處理
疑難排解
layout: book-zh title: 自定制 shell 提示符
查找文件
layout: book-zh title: vi 簡介
shell 環(huán)境
什么是 shell
編譯程序
鍵盤高級操作技巧
流程控制:case 分支
流程控制:if 分支結構
layout: book-zh title: 軟件包管理
進程
存儲媒介
格式化輸出
編寫第一個 Shell 腳本
啟動一個項目
流程控制:while/until 循環(huán)
文件系統(tǒng)中跳轉
字符串和數(shù)字
讀取鍵盤輸入
歸檔和備份
探究操作系統(tǒng)
流程控制:for 循環(huán)
自頂向下設計
數(shù)組
操作文件和目錄
奇珍異寶
從 shell 眼中看世界
正則表達式

歸檔和備份

計算機系統(tǒng)管理員的一個主要任務就是保護系統(tǒng)的數(shù)據(jù)安全,其中一種方法是通過時時備份系統(tǒng)文件,來保護 數(shù)據(jù)。即使你不是一名系統(tǒng)管理員,像做做拷貝或者在各個位置和設備之間移動大量的文件,通常也是很有幫助的。 在這一章中,我們將會看看幾個經常用來管理文件集合的程序。它們就是文件壓縮程序:

  • gzip – 壓縮或者展開文件

  • bzip2 – 塊排序文件壓縮器

歸檔程序:

  • tar – 磁帶打包工具

  • zip – 打包和壓縮文件

還有文件同步程序:

  • rsync – 同步遠端文件和目錄

壓縮文件

縱觀計算領域的發(fā)展歷史,人們努力想把最多的數(shù)據(jù)存放到到最小的可用空間中,不管是內存,存儲設備 還是網絡帶寬。今天我們把許多數(shù)據(jù)服務都看作是理所當然的事情,但是諸如便攜式音樂播放器, 高清電視,或寬帶網絡之類的存在都應歸功于高效的數(shù)據(jù)壓縮技術。

數(shù)據(jù)壓縮就是一個刪除冗余數(shù)據(jù)的過程。讓我們考慮一個假想的例子,比方說我們有一張100*100像素的 純黑的圖片文件。根據(jù)數(shù)據(jù)存儲方案(假定每個像素占24位,或者3個字節(jié)),那么這張圖像將會占用 30,000個字節(jié)的存儲空間:

100 * 100 * 3 = 30,000

一張單色圖像包含的數(shù)據(jù)全是多余的。我們要是聰明的話,可以用這種方法來編碼這些數(shù)據(jù), 我們只要簡單地描述這個事實,我們有3萬個黑色的像素數(shù)據(jù)塊。所以,我們不存儲包含3萬個0 (通常在圖像文件中,黑色由0來表示)的數(shù)據(jù)塊,取而代之,我們把這些數(shù)據(jù)壓縮為數(shù)字30,000, 后跟一個0,來表示我們的數(shù)據(jù)。這種數(shù)據(jù)壓縮方案被稱為游程編碼,是一種最基本的壓縮技術。

壓縮算法(數(shù)學技巧被用來執(zhí)行壓縮任務)分為兩大類,無損壓縮和有損壓縮。無損壓縮保留了 原始文件的所有數(shù)據(jù)。這意味著,當還原一個壓縮文件的時候,還原的文件與原文件一模一樣。 而另一方面,有損壓縮,執(zhí)行壓縮操作時會刪除數(shù)據(jù),允許更大的壓縮。當一個有損文件被還原的時候, 它與原文件不相匹配; 相反,它是一個近似值。有損壓縮的例子有 JPEG(圖像)文件和 MP3(音頻)文件。 在我們的討論中,我們將看看完全無損壓縮,因為計算機中的大多數(shù)數(shù)據(jù)是不能容忍丟失任何數(shù)據(jù)的。

gzip

這個 gzip 程序被用來壓縮一個或多個文件。當執(zhí)行 gzip 命令時,則原始文件的壓縮版會替代原始文件。 相對應的 gunzip 程序被用來把壓縮文件復原為沒有被壓縮的版本。這里有個例子:

[me@linuxbox ~]$ ls -l /etc > foo.txt
[me@linuxbox ~]$ ls -l foo.*
-rw-r--r-- 1 me     me 15738 2008-10-14 07:15 foo.txt
[me@linuxbox ~]$ gzip foo.txt
[me@linuxbox ~]$ ls -l foo.*
-rw-r--r-- 1 me     me 3230 2008-10-14 07:15 foo.txt.gz
[me@linuxbox ~]$ gunzip foo.txt.gz
[me@linuxbox ~]$ ls -l foo.*
-rw-r--r-- 1 me     me 15738 2008-10-14 07:15 foo.txt

在這個例子里,我們創(chuàng)建了一個名為 foo.txt 的文本文件,其內容包含一個目錄的列表清單。 接下來,我們運行 gzip 命令,它會把原始文件替換為一個叫做 foo.txt.gz 的壓縮文件。在 foo.* 文件列表中,我們看到原始文件已經被壓縮文件替代了,并將這個壓縮文件大約是原始 文件的十五分之一。我們也能看到壓縮文件與原始文件有著相同的權限和時間戳。

接下來,我們運行 gunzip 程序來解壓縮文件。隨后,我們能見到壓縮文件已經被原始文件替代了, 同樣地保留了相同的權限和時間戳。

gzip 命令有許多選項。這里列出了一些:

表19-1: gzip 選項
選項 說明
-c 把輸出寫入到標準輸出,并且保留原始文件。也有可能用--stdout 和--to-stdout 選項來指定。
-d 解壓縮。正如 gunzip 命令一樣。也可以用--decompress 或者--uncompress 選項來指定.
-f 強制壓縮,即使原始文件的壓縮文件已經存在了,也要執(zhí)行。也可以用--force 選項來指定。
-h 顯示用法信息。也可用--help 選項來指定。
-l 列出每個被壓縮文件的壓縮數(shù)據(jù)。也可用--list 選項。
-r 若命令的一個或多個參數(shù)是目錄,則遞歸地壓縮目錄中的文件。也可用--recursive 選項來指定。
-t 測試壓縮文件的完整性。也可用--test 選項來指定。
-v 顯示壓縮過程中的信息。也可用--verbose 選項來指定。
-number 設置壓縮指數(shù)。number 是一個在1(最快,最小壓縮)到9(最慢,最大壓縮)之間的整數(shù)。 數(shù)值1和9也可以各自用--fast 和--best 選項來表示。默認值是整數(shù)6。

返回到我們之前的例子中:

[me@linuxbox ~]$ gzip foo.txt
[me@linuxbox ~]$ gzip -tv foo.txt.gz
foo.txt.gz: OK
[me@linuxbox ~]$ gzip -d foo.txt.gz

這里,我們用壓縮文件來替代文件 foo.txt,壓縮文件名為 foo.txt.gz。下一步,我們測試了壓縮文件 的完整性,使用了-t 和-v 選項。

[me@linuxbox ~]$ ls -l /etc | gzip > foo.txt.gz

這個命令創(chuàng)建了一個目錄列表的壓縮文件。

這個 gunzip 程序,會解壓縮 gzip 文件,假定那些文件名的擴展名是.gz,所以沒有必要指定它, 只要指定的名字與現(xiàn)有的未壓縮文件不沖突就可以:

[me@linuxbox ~]$ gunzip foo.txt

如果我們的目標只是為了瀏覽一下壓縮文本文件的內容,我們可以這樣做:

[me@linuxbox ~]$ gunzip -c foo.txt | less

另外,對應于 gzip 還有一個程序,叫做 zcat,它等同于帶有-c 選項的 gunzip 命令。 它可以被用來如 cat 命令作用于 gzip 壓縮文件:

[me@linuxbox ~]$ zcat foo.txt.gz | less

小貼士: 還有一個 zless 程序。它與上面的管道線有相同的功能。


bzip2

這個 bzip2 程序,由 Julian Seward 開發(fā),與 gzip 程序相似,但是使用了不同的壓縮算法, 舍棄了壓縮速度,而實現(xiàn)了更高的壓縮級別。在大多數(shù)情況下,它的工作模式等同于 gzip。 由 bzip2 壓縮的文件,用擴展名 .bz2 來表示:

[me@linuxbox ~]$ ls -l /etc > foo.txt
[me@linuxbox ~]$ ls -l foo.txt
-rw-r--r-- 1 me     me      15738 2008-10-17 13:51 foo.txt
[me@linuxbox ~]$ bzip2 foo.txt
[me@linuxbox ~]$ ls -l foo.txt.bz2
-rw-r--r-- 1 me     me      2792 2008-10-17 13:51 foo.txt.bz2
[me@linuxbox ~]$ bunzip2 foo.txt.bz2

正如我們所看到的,bzip2 程序使用起來和 gzip 程序一樣。我們之前討論的 gzip 程序的所有選項(除了-r) ,bzip2 程序同樣也支持。注意,然而,壓縮級別選項(-number)對于 bzip2 程序來說,有少許不同的含義。 伴隨著 bzip2 程序,有 bunzip2 和 bzcat 程序來解壓縮文件。bzip2 文件也帶有 bzip2recover 程序,其會 試圖恢復受損的 .bz2 文件。

不要強迫性壓縮

我偶然見到人們試圖用高效的壓縮算法,來壓縮一個已經被壓縮過的文件,通過這樣做:

$ gzip picture.jpg

不要這樣。你可能只是在浪費時間和空間!如果你再次壓縮已經壓縮過的文件,實際上你 會得到一個更大的文件。這是因為所有的壓縮技術都會涉及一些開銷,文件中會被添加描述 此次壓縮過程的信息。如果你試圖壓縮一個已經不包含多余信息的文件,那么再次壓縮不會節(jié)省 空間,以抵消額外的花費。

歸檔文件

一個常見的,與文件壓縮結合一塊使用的文件管理任務是歸檔。歸檔就是收集許多文件,并把它們 捆綁成一個大文件的過程。歸檔經常作為系統(tǒng)備份的一部分來使用。當把舊數(shù)據(jù)從一個系統(tǒng)移到某 種類型的長期存儲設備中時,也會用到歸檔程序。

tar

在類 Unix 的軟件世界中,這個 tar 程序是用來歸檔文件的經典工具。它的名字,是 tape archive 的簡稱,揭示了它的根源,它是一款制作磁帶備份的工具。而它仍然被用來完成傳統(tǒng)任務, 它也同樣適用于其它的存儲設備。我們經??吹綌U展名為 .tar 或者 .tgz 的文件,它們各自表示“普通” 的 tar 包和被 gzip 程序壓縮過的 tar 包。一個 tar 包可以由一組獨立的文件,一個或者多個目錄,或者 兩者混合體組成。命令語法如下:

tar mode[options] pathname...

這里的 mode 是指以下操作模式(這里只展示了一部分,查看 tar 的手冊來得到完整列表)之一:

表19-2: tar 模式
模式 說明
c 為文件和/或目錄列表創(chuàng)建歸檔文件。
x 抽取歸檔文件。
r 追加具體的路徑到歸檔文件的末尾。
t 列出歸檔文件的內容。

tar 命令使用了稍微有點奇怪的方式來表達它的選項,所以我們需要一些例子來展示它是 怎樣工作的。首先,讓我們重新創(chuàng)建之前我們用過的操練場:

[me@linuxbox ~]$ mkdir -p playground/dir-{00{1..9},0{10..99},100}
[me@linuxbox ~]$ touch playground/dir-{00{1..9},0{10..99},100}/file-{A-Z}

下一步,讓我們創(chuàng)建整個操練場的 tar 包:

[me@linuxbox ~]$ tar cf playground.tar playground

這個命令創(chuàng)建了一個名為 playground.tar 的 tar 包,其包含整個 playground 目錄層次結果。我們 可以看到模式 c 和選項 f,其被用來指定這個 tar 包的名字,模式和選項可以寫在一起,而且不 需要開頭的短橫線。注意,然而,必須首先指定模式,然后才是其它的選項。

要想列出歸檔文件的內容,我們可以這樣做:

[me@linuxbox ~]$ tar tf playground.tar

為了得到更詳細的列表信息,我們可以添加選項 v:

[me@linuxbox ~]$ tar tvf playground.tar

現(xiàn)在,抽取 tar 包 playground 到一個新位置。我們先創(chuàng)建一個名為 foo 的新目錄,更改目錄, 然后抽取 tar 包中的文件:

[me@linuxbox ~]$ mkdir foo
[me@linuxbox ~]$ cd foo
[me@linuxbox ~]$ tar xf ../playground.tar
[me@linuxbox ~]$ ls
playground

如果我們檢查 ~/foo/playground 目錄中的內容,會看到這個歸檔文件已經被成功地安裝了,就是創(chuàng)建了 一個精確的原始文件的副本。有一個警告,然而:除非你是超級用戶,要不然從歸檔文件中抽取的文件 和目錄的所有權由執(zhí)行此復原操作的用戶所擁有,而不屬于原始所有者。

tar 命令另一個有趣的行為是它處理歸檔文件路徑名的方式。默認情況下,路徑名是相對的,而不是絕對 路徑。當創(chuàng)建歸檔文件的時候,tar 命令會簡單地刪除路徑名開頭的斜杠。為了說明問題,我們將會 重新創(chuàng)建我們的歸檔文件,這次指定一個絕對路徑:

[me@linuxbox foo]$ cd
[me@linuxbox ~]$ tar cf playground2.tar ~/playground

記住,當按下回車鍵后,~/playground 會展開成 /home/me/playground,所以我們將會得到一個 絕對路徑名。接下來,和之前一樣我們會抽取歸檔文件,觀察發(fā)生什么事情:

[me@linuxbox ~]$ cd foo
[me@linuxbox foo]$ tar xf ../playground2.tar
[me@linuxbox foo]$ ls
home     playground
[me@linuxbox foo]$ ls home
me
[me@linuxbox foo]$ ls home/me
playground

這里我們看到當我們抽取第二個歸檔文件時,它重新創(chuàng)建了 home/me/playground 目錄, 相對于我們當前的工作目錄,~/foo,而不是相對于 root 目錄,作為帶有絕對路徑名的案例。 這看起來似乎是一種奇怪的工作方式,但事實上這種方式很有用,因為這樣就允許我們抽取文件 到任意位置,而不是強制地把抽取的文件放置到原始目錄下。加上 verbose(v)選項,重做 這個練習,將會展現(xiàn)更加詳細的信息。

讓我們考慮一個假設,tar 命令的實際應用。假定我們想要復制家目錄及其內容到另一個系統(tǒng)中, 并且有一個大容量的 USB 硬盤,可以把它作為傳輸工具。在現(xiàn)代 Linux 系統(tǒng)中, 這個硬盤會被“自動地”掛載到 /media 目錄下。我們也假定硬盤中有一個名為 BigDisk 的邏輯卷。 為了制作 tar 包,我們可以這樣做:

[me@linuxbox ~]$ sudo tar cf /media/BigDisk/home.tar /home

tar 包制作完成之后,我們卸載硬盤,然后把它連接到第二個計算機上。再一次,此硬盤被 掛載到 /media/BigDisk 目錄下。為了抽取歸檔文件,我們這樣做:

[me@linuxbox2 ~]$ cd /
[me@linuxbox2 /]$ sudo tar xf /media/BigDisk/home.tar

值得注意的一點是,因為歸檔文件中的所有路徑名都是相對的,所以首先我們必須更改目錄到根目錄下, 這樣抽取的文件路徑就相對于根目錄了。

當抽取一個歸檔文件時,有可能限制從歸檔文件中抽取什么內容。例如,如果我們想要抽取單個文件, 可以這樣實現(xiàn):

tar xf archive.tar pathname

通過給命令添加末尾的路徑名,tar 命令就只會恢復指定的文件??梢灾付ǘ鄠€路徑名。注意 路徑名必須是完全的,精準的相對路徑名,就如存儲在歸檔文件中的一樣。當指定路徑名的時候, 通常不支持通配符;然而,GNU 版本的 tar 命令(在 Linux 發(fā)行版中最常出現(xiàn))通過 --wildcards 選項來 支持通配符。這個例子使用了之前 playground.tar 文件:

[me@linuxbox ~]$ cd foo
[me@linuxbox foo]$ tar xf ../playground2.tar --wildcards 'home/me/playground/dir-\*/file-A'

這個命令將只會抽取匹配特定路徑名的文件,路徑名中包含了通配符 dir-*。

tar 命令經常結合 find 命令一起來制作歸檔文件。在這個例子里,我們將會使用 find 命令來 產生一個文件集合,然后這些文件被包含到歸檔文件中。

[me@linuxbox ~]$ find playground -name 'file-A' -exec tar rf playground.tar '{}' '+'

這里我們使用 find 命令來匹配 playground 目錄中所有名為 file-A 的文件,然后使用-exec 行為,來 喚醒帶有追加模式(r)的 tar 命令,把匹配的文件添加到歸檔文件 playground.tar 里面。

使用 tar 和 find 命令,來創(chuàng)建逐漸增加的目錄樹或者整個系統(tǒng)的備份,是個不錯的方法。通過 find 命令匹配新于某個時間戳的文件,我們就能夠創(chuàng)建一個歸檔文件,其只包含新于上一個 tar 包的文件, 假定這個時間戳文件恰好在每個歸檔文件創(chuàng)建之后被更新了。

tar 命令也可以利用標準輸出和輸入。這里是一個完整的例子:

[me@linuxbox foo]$ cd
[me@linuxbox ~]$ find playground -name 'file-A' | tar cf - --files-from=-
   | gzip > playground.tgz

在這個例子里面,我們使用 find 程序產生了一個匹配文件列表,然后把它們管道到 tar 命令中。 如果指定了文件名“-”,則其被看作是標準輸入或輸出,正是所需(順便說一下,使用“-”來表示 標準輸入/輸出的慣例,也被大量的其它程序使用)。這個 --file-from 選項(也可以用 -T 來指定) 導致 tar 命令從一個文件而不是命令行來讀入它的路徑名列表。最后,這個由 tar 命令產生的歸檔 文件被管道到 gzip 命令中,然后創(chuàng)建了壓縮歸檔文件 playground.tgz。此 .tgz 擴展名是命名 由 gzip 壓縮的 tar 文件的常規(guī)擴展名。有時候也會使用 .tar.gz 這個擴展名。

雖然我們使用 gzip 程序來制作我們的壓縮歸檔文件,但是現(xiàn)在的 GUN 版本的 tar 命令 ,gzip 和 bzip2 壓縮兩者都直接支持,各自使用 z 和 j 選項。以我們之前的例子為基礎, 我們可以這樣簡化它:

[me@linuxbox ~]$ find playground -name 'file-A' | tar czf playground.tgz -T -

如果我們本要創(chuàng)建一個由 bzip2 壓縮的歸檔文件,我們可以這樣做:

[me@linuxbox ~]$ find playground -name 'file-A' | tar cjf playground.tbz -T -

通過簡單地修改壓縮選項,把 z 改為 j(并且把輸出文件的擴展名改為 .tbz,來指示一個 bzip2 壓縮文件), 就使 bzip2 命令壓縮生效了。另一個 tar 命令與標準輸入和輸出的有趣使用,涉及到在系統(tǒng)之間經過 網絡傳輸文件。假定我們有兩臺機器,每臺都運行著類 Unix,且裝備著 tar 和 ssh 工具的操作系統(tǒng)。 在這種情景下,我們可以把一個目錄從遠端系統(tǒng)(名為 remote-sys)傳輸?shù)轿覀兊谋镜叵到y(tǒng)中:

[me@linuxbox ~]$ mkdir remote-stuff
[me@linuxbox ~]$ cd remote-stuff
[me@linuxbox remote-stuff]$ ssh remote-sys 'tar cf - Documents' | tar xf -
me@remote-sys’s password:
[me@linuxbox remote-stuff]$ ls
Documents

這里我們能夠從遠端系統(tǒng) remote-sys 中復制目錄 Documents 到本地系統(tǒng)名為 remote-stuff 目錄中。 我們怎樣做的呢?首先,通過使用 ssh 命令在遠端系統(tǒng)中啟動 tar 程序。你可記得 ssh 允許我們 在遠程聯(lián)網的計算機上執(zhí)行程序,并且在本地系統(tǒng)中看到執(zhí)行結果——遠端系統(tǒng)中產生的輸出結果 被發(fā)送到本地系統(tǒng)中查看。我們可以利用。在本地系統(tǒng)中,我們執(zhí)行 tar 命令,

zip

這個 zip 程序既是壓縮工具,也是一個打包工具。這程序使用的文件格式,Windows 用戶比較熟悉, 因為它讀取和寫入.zip 文件。然而,在 Linux 中 gzip 是主要的壓縮程序,而 bzip2則位居第二。

在 zip 命令最基本的使用中,可以這樣喚醒 zip 命令:

zip options zipfile file...

例如,制作一個 playground 的 zip 版本的文件包,這樣做:

[me@linuxbox ~]$ zip -r playground.zip playground

除非我們包含-r 選項,要不然只有 playground 目錄(沒有任何它的內容)被存儲。雖然會自動添加 .zip 擴展名,但為了清晰起見,我們還是包含文件擴展名。

在創(chuàng)建 zip 版本的文件包時,zip 命令通常會顯示一系列的信息:

adding: playground/dir-020/file-Z (stored 0%)
adding: playground/dir-020/file-Y (stored 0%)
adding: playground/dir-020/file-X (stored 0%)
adding: playground/dir-087/ (stored 0%)
adding: playground/dir-087/file-S (stored 0%)

這些信息顯示了添加到文件包中每個文件的狀態(tài)。zip 命令會使用兩種存儲方法之一,來添加 文件到文件包中:要不它會“store”沒有壓縮的文件,正如這里所示,或者它會“deflate”文件, 執(zhí)行壓縮操作。在存儲方法之后顯示的數(shù)值表明了壓縮量。因為我們的 playground 目錄 只是包含空文件,沒有對它的內容執(zhí)行壓縮操作。

使用 unzip 程序,來直接抽取一個 zip 文件的內容。

[me@linuxbox ~]$ cd foo
[me@linuxbox foo]$ unzip ../playground.zip

對于 zip 命令(與 tar 命令相反)要注意一點,就是如果指定了一個已經存在的文件包,其被更新 而不是被替代。這意味著會保留此文件包,但是會添加新文件,同時替換匹配的文件??梢粤谐?文件或者有選擇地從一個 zip 文件包中抽取文件,只要給 unzip 命令指定文件名:

[me@linuxbox ~]$ unzip -l playground.zip playground/dir-87/file-Z
Archive: ../playground.zip
    Length      Date    Time    Name

         0    10-05-08  09:25   playground/dir-87/file-Z

         0                      1 file
[me@linuxbox ~]$ cd foo
[me@linuxbox foo]$ unzip ./playground.zip playground/dir-87/file-Z
Archive: ../playground.zip
replace playground/dir-87/file-Z? [y]es, [n]o, [A]ll, [N]one,
[r]ename: y
extracting: playground/dir-87/file-Z

使用-l 選項,導致 unzip 命令只是列出文件包中的內容而沒有抽取文件。如果沒有指定文件, unzip 程序將會列出文件包中的所有文件。添加這個-v 選項會增加列表的冗余信息。注意當抽取的 文件與已經存在的文件沖突時,會在替代此文件之前提醒用戶。

像 tar 命令一樣,zip 命令能夠利用標準輸入和輸出,雖然它的實施不大有用。通過-@選項,有可能把一系列的 文件名管道到 zip 命令。

[me@linuxbox foo]$ cd
[me@linuxbox ~]$ find playground -name "file-A" | zip -@ file-A.zip

這里我們使用 find 命令產生一系列與“file-A”相匹配的文件列表,并且把此列表管道到 zip 命令, 然后創(chuàng)建包含所選文件的文件包 file-A.zip。

zip 命令也支持把它的輸出寫入到標準輸出,但是它的使用是有限的,因為很少的程序能利用輸出。 不幸地是,這個 unzip 程序,不接受標準輸入。這就阻止了 zip 和 unzip 一塊使用,像 tar 命令那樣, 來復制網絡上的文件。

然而,zip 命令可以接受標準輸入,所以它可以被用來壓縮其它程序的輸出:

[me@linuxbox ~]$ ls -l /etc/ | zip ls-etc.zip -
adding: - (deflated 80%)

在這個例子里,我們把 ls 命令的輸出管道到 zip 命令。像 tar 命令,zip 命令把末尾的橫杠解釋為 “使用標準輸入作為輸入文件。”

這個 unzip 程序允許它的輸出發(fā)送到標準輸出,當指定了-p 選項之后:

[me@linuxbox ~]$ unzip -p ls-etc.zip | less

我們討論了一些 zip/unzip 可以完成的基本操作。它們兩個都有許多選項,其增加了 命令的靈活性,雖然一些選項只針對于特定的平臺。zip 和 unzip 命令的說明手冊都相當不錯, 并且包含了有用的實例。然而,這些程序的主要用途是為了和 Windows 系統(tǒng)交換文件, 而不是在 Linux 系統(tǒng)中執(zhí)行壓縮和打包操作,tar 和 gzip 程序在 Linux 系統(tǒng)中更受歡迎。

同步文件和目錄

維護系統(tǒng)備份的常見策略是保持一個或多個目錄與另一個本地系統(tǒng)(通常是某種可移動的存儲設備) 或者遠端系統(tǒng)中的目錄(或多個目錄)同步。我們可能,例如有一個正在開發(fā)的網站的本地備份, 需要時不時的與遠端網絡服務器中的文件備份保持同步。在類 Unix 系統(tǒng)的世界里,能完成此任務且 備受人們喜愛的工具是 rsync。這個程序能同步本地與遠端的目錄,通過使用 rsync 遠端更新協(xié)議,此協(xié)議 允許 rsync 快速地檢測兩個目錄的差異,執(zhí)行最小量的復制來達到目錄間的同步。比起其它種類的復制程序, 這就使 rsync 命令非??焖俸透咝?。

rsync 被這樣喚醒:

rsync options source destination

這里 source 和 destination 是下列選項之一:

  • 一個本地文件或目錄

  • 一個遠端文件或目錄,以[user@]host:path 的形式存在

  • 一個遠端 rsync 服務器,由 rsync://[user@]host[:port]/path 指定

注意 source 和 destination 兩者之一必須是本地文件。rsync 不支持遠端到遠端的復制

讓我們試著對一些本地文件使用 rsync 命令。首先,清空我們的 foo 目錄:

[me@linuxbox ~]$ rm -rf foo/*

下一步,我們將同步 playground 目錄和它在 foo 目錄中相對應的副本

[me@linuxbox ~]$ rsync -av playground foo

我們包括了-a 選項(遞歸和保護文件屬性)和-v 選項(冗余輸出), 來在 foo 目錄中制作一個 playground 目錄的鏡像。當這個命令執(zhí)行的時候, 我們將會看到一系列的文件和目錄被復制。在最后,我們將看到一條像這樣的總結信息:

sent 135759 bytes received 57870 bytes 387258.00 bytes/sec
total size is 3230 speedup is 0.02

說明復制的數(shù)量。如果我們再次運行這個命令,我們將會看到不同的結果:

[me@linuxbox ~]$ rsync -av playgound foo
building file list ... done
sent 22635 bytes received 20 bytes
total size is 3230 speedup is 0.14
45310.00 bytes/sec

注意到沒有文件列表。這是因為 rsync 程序檢測到在目錄~/playground 和 ~/foo/playground 之間 不存在差異,因此它不需要復制任何數(shù)據(jù)。如果我們在 playground 目錄中修改一個文件,然后 再次運行 rsync 命令:

[me@linuxbox ~]$ touch playground/dir-099/file-Z
[me@linuxbox ~]$ rsync -av playground foo
building file list ... done
playground/dir-099/file-Z
sent 22685 bytes received 42 bytes 45454.00 bytes/sec
total size is 3230 speedup is 0.14

我們看到 rsync 命令檢測到更改,并且只是復制了更新的文件。作為一個實際的例子, 讓我們考慮一個假想的外部硬盤,之前我們在 tar 命令中用到過的。如果我們再次把此 硬盤連接到我們的系統(tǒng)中,它被掛載到/media/BigDisk 目錄下,我們可以執(zhí)行一個有 用的系統(tǒng)備份了,首先在外部硬盤上創(chuàng)建一個目錄,名為/backup,然后使用 rsync 程序 從我們的系統(tǒng)中復制最重要的數(shù)據(jù)到此外部硬盤上:

[me@linuxbox ~]$ mkdir /media/BigDisk/backup
[me@linuxbox ~]$ sudo rsync -av --delete /etc /home /usr/local /media/BigDisk/backup

在這個例子里,我們把/etc,/home,和/usr/local 目錄從我們的系統(tǒng)中復制到假想的存儲設備中。 我們包含了--delete 這個選項,來刪除可能在備份設備中已經存在但卻不再存在于源設備中的文件, (這與我們第一次創(chuàng)建備份無關,但是會在隨后的復制操作中有用途)。掛載外部驅動器,運行 rsync 命令,不斷重復這個過程,是一個不錯的(雖然不理想)方式來保存少量的系統(tǒng)備份文件。 當然,別名會對這個操作更有幫助些。我們將會創(chuàng)建一個別名,并把它添加到.bashrc 文件中, 來提供這個特性:

alias backup='sudo rsync -av --delete /etc /home /usr/local /media/BigDisk/backup'

現(xiàn)在我們所做的事情就是連接外部驅動器,然后運行 backup 命令來完成工作。

在網絡間使用 rsync 命令

rsync 程序的真正好處之一,是它可以被用來在網絡間復制文件。畢竟,rsync 中的“r”象征著“remote”。 遠程復制可以通過兩種方法完成。第一個方法要求另一個系統(tǒng)已經安裝了 rsync 程序,還安裝了 遠程 shell 程序,比如 ssh。比方說我們本地網絡中的一個系統(tǒng)有大量可用的硬盤空間,我們想要 用遠程系統(tǒng)來代替一個外部驅動器,來執(zhí)行文件備份操作。假定遠程系統(tǒng)中有一個名為/backup 的目錄, 其用來存放我們傳送的文件,我們這樣做:

[me@linuxbox ~]$ sudo rsync -av --delete --rsh=ssh /etc /home /usr/local remote-sys:/backup

我們對命令做了兩處修改,來方便網絡間文件復制。首先,我們添加了--rsh=ssh 選項,其指示 rsync 使用 ssh 程序作為它的遠程 shell。以這種方式,我們就能夠使用一個 ssh 加密通道,把數(shù)據(jù) 安全地傳送到遠程主機中。其次,通過在目標路徑名前加上遠端主機的名字(在這種情況下, 遠端主機名為 remote-sys),來指定遠端主機。

rsync 可以被用來在網絡間同步文件的第二種方式是通過使用 rsync 服務器。rsync 可以被配置為一個 守護進程,監(jiān)聽即將到來的同步請求。這樣做經常是為了允許一個遠程系統(tǒng)的鏡像。例如,Red Hat 軟件中心為它的 Fedora 發(fā)行版,維護著一個巨大的正在開發(fā)中的軟件包的倉庫。對于軟件測試人員, 在發(fā)行周期的測試階段,鏡像這些軟件集合是非常有幫助的。因為倉庫中的這些文件會頻繁地 (通常每天不止一次)改動,定期同步本地鏡像,這是可取的,而不是大量地拷貝軟件倉庫。 這些軟件庫之一被維護在 Georgia Tech;我們可以使用本地 rsync 程序和它們的 rsync 服務器來鏡像它。

[me@linuxbox ~]$ mkdir fedora-devel
[me@linuxbox ~]$ rsync -av -delete rsync://rsync.gtlib.gatech.edu/fedora-linux-
 core/development/i386/os fedora-devel

在這個例子里,我們使用了遠端 rsync 服務器的 URI,其由協(xié)議(rsync://),遠端主機名 (rsync.gtlib.gatech.edu),和軟件倉庫的路徑名組成。

拓展閱讀

  • 在這里討論的所有命令的手冊文檔都相當清楚明白,并且包含了有用的例子。另外, GNU 版本的 tar 命令有一個不錯的在線文檔??梢栽谙旅骀溄犹幷业剑?/p>

    http://www.gnu.org/software/tar/manual/index.html

上一篇:查找文件下一篇:打印