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

歸檔和備份

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

  • gzip – 壓縮或者展開文件

  • bzip2 – 塊排序文件壓縮器

歸檔程序:

  • tar – 磁帶打包工具

  • zip – 打包和壓縮文件

還有文件同步程序:

  • rsync – 同步遠(yuǎn)端文件和目錄

壓縮文件

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

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

100 * 100 * 3 = 30,000

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

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

gzip

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

[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 的文本文件,其內(nèi)容包含一個目錄的列表清單。 接下來,我們運(yùn)行 gzip 命令,它會把原始文件替換為一個叫做 foo.txt.gz 的壓縮文件。在 foo.* 文件列表中,我們看到原始文件已經(jīng)被壓縮文件替代了,并將這個壓縮文件大約是原始 文件的十五分之一。我們也能看到壓縮文件與原始文件有著相同的權(quán)限和時間戳。

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

gzip 命令有許多選項(xiàng)。這里列出了一些:

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

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

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

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

[me@linuxbox ~]$ gunzip foo.txt

如果我們的目標(biāo)只是為了瀏覽一下壓縮文本文件的內(nèi)容,我們可以這樣做:

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

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

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

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


bzip2

這個 bzip2 程序,由 Julian Seward 開發(fā),與 gzip 程序相似,但是使用了不同的壓縮算法, 舍棄了壓縮速度,而實(shí)現(xiàn)了更高的壓縮級別。在大多數(shù)情況下,它的工作模式等同于 gzip。 由 bzip2 壓縮的文件,用擴(kuò)展名 .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 程序的所有選項(xiàng)(除了-r) ,bzip2 程序同樣也支持。注意,然而,壓縮級別選項(xiàng)(-number)對于 bzip2 程序來說,有少許不同的含義。 伴隨著 bzip2 程序,有 bunzip2 和 bzcat 程序來解壓縮文件。bzip2 文件也帶有 bzip2recover 程序,其會 試圖恢復(fù)受損的 .bz2 文件。

不要強(qiáng)迫性壓縮

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

$ gzip picture.jpg

不要這樣。你可能只是在浪費(fèi)時間和空間!如果你再次壓縮已經(jīng)壓縮過的文件,實(shí)際上你 會得到一個更大的文件。這是因?yàn)樗械膲嚎s技術(shù)都會涉及一些開銷,文件中會被添加描述 此次壓縮過程的信息。如果你試圖壓縮一個已經(jīng)不包含多余信息的文件,那么再次壓縮不會節(jié)省 空間,以抵消額外的花費(fèi)。

歸檔文件

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

tar

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

tar mode[options] pathname...

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

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

tar 命令使用了稍微有點(diǎn)奇怪的方式來表達(dá)它的選項(xiàng),所以我們需要一些例子來展示它是 怎樣工作的。首先,讓我們重新創(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 目錄層次結(jié)果。我們 可以看到模式 c 和選項(xiàng) f,其被用來指定這個 tar 包的名字,模式和選項(xiàng)可以寫在一起,而且不 需要開頭的短橫線。注意,然而,必須首先指定模式,然后才是其它的選項(xiàng)。

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

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

為了得到更詳細(xì)的列表信息,我們可以添加選項(xiàng) 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 目錄中的內(nèi)容,會看到這個歸檔文件已經(jīng)被成功地安裝了,就是創(chuàng)建了 一個精確的原始文件的副本。有一個警告,然而:除非你是超級用戶,要不然從歸檔文件中抽取的文件 和目錄的所有權(quán)由執(zhí)行此復(fù)原操作的用戶所擁有,而不屬于原始所有者。

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

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

記住,當(dāng)按下回車鍵后,~/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

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

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

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

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

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

值得注意的一點(diǎn)是,因?yàn)闅w檔文件中的所有路徑名都是相對的,所以首先我們必須更改目錄到根目錄下, 這樣抽取的文件路徑就相對于根目錄了。

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

tar xf archive.tar pathname

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

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

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

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

[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 命令也可以利用標(biāo)準(zhǔn)輸出和輸入。這里是一個完整的例子:

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

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

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

[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 -

通過簡單地修改壓縮選項(xiàng),把 z 改為 j(并且把輸出文件的擴(kuò)展名改為 .tbz,來指示一個 bzip2 壓縮文件), 就使 bzip2 命令壓縮生效了。另一個 tar 命令與標(biāo)準(zhǔn)輸入和輸出的有趣使用,涉及到在系統(tǒng)之間經(jīng)過 網(wǎng)絡(luò)傳輸文件。假定我們有兩臺機(jī)器,每臺都運(yùn)行著類 Unix,且裝備著 tar 和 ssh 工具的操作系統(tǒng)。 在這種情景下,我們可以把一個目錄從遠(yuǎn)端系統(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

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

zip

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

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

zip options zipfile file...

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

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

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

在創(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ù)值表明了壓縮量。因?yàn)槲覀兊?playground 目錄 只是包含空文件,沒有對它的內(nèi)容執(zhí)行壓縮操作。

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

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

對于 zip 命令(與 tar 命令相反)要注意一點(diǎn),就是如果指定了一個已經(jīng)存在的文件包,其被更新 而不是被替代。這意味著會保留此文件包,但是會添加新文件,同時替換匹配的文件。可以列出 文件或者有選擇地從一個 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 選項(xiàng),導(dǎo)致 unzip 命令只是列出文件包中的內(nèi)容而沒有抽取文件。如果沒有指定文件, unzip 程序?qū)谐鑫募械乃形募?。添加這個-v 選項(xiàng)會增加列表的冗余信息。注意當(dāng)抽取的 文件與已經(jīng)存在的文件沖突時,會在替代此文件之前提醒用戶。

像 tar 命令一樣,zip 命令能夠利用標(biāo)準(zhǔn)輸入和輸出,雖然它的實(shí)施不大有用。通過-@選項(xiàng),有可能把一系列的 文件名管道到 zip 命令。

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

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

zip 命令也支持把它的輸出寫入到標(biāo)準(zhǔn)輸出,但是它的使用是有限的,因?yàn)楹苌俚某绦蚰芾幂敵觥?不幸地是,這個 unzip 程序,不接受標(biāo)準(zhǔn)輸入。這就阻止了 zip 和 unzip 一塊使用,像 tar 命令那樣, 來復(fù)制網(wǎng)絡(luò)上的文件。

然而,zip 命令可以接受標(biāo)準(zhǔn)輸入,所以它可以被用來壓縮其它程序的輸出:

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

在這個例子里,我們把 ls 命令的輸出管道到 zip 命令。像 tar 命令,zip 命令把末尾的橫杠解釋為 “使用標(biāo)準(zhǔn)輸入作為輸入文件?!?/p>

這個 unzip 程序允許它的輸出發(fā)送到標(biāo)準(zhǔn)輸出,當(dāng)指定了-p 選項(xiàng)之后:

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

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

同步文件和目錄

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

rsync 被這樣喚醒:

rsync options source destination

這里 source 和 destination 是下列選項(xiàng)之一:

  • 一個本地文件或目錄

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

  • 一個遠(yuǎn)端 rsync 服務(wù)器,由 rsync://[user@]host[:port]/path 指定

注意 source 和 destination 兩者之一必須是本地文件。rsync 不支持遠(yuǎn)端到遠(yuǎn)端的復(fù)制

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

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

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

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

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

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

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

[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

注意到?jīng)]有文件列表。這是因?yàn)?rsync 程序檢測到在目錄~/playground 和 ~/foo/playground 之間 不存在差異,因此它不需要復(fù)制任何數(shù)據(jù)。如果我們在 playground 目錄中修改一個文件,然后 再次運(yùn)行 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 命令檢測到更改,并且只是復(fù)制了更新的文件。作為一個實(shí)際的例子, 讓我們考慮一個假想的外部硬盤,之前我們在 tar 命令中用到過的。如果我們再次把此 硬盤連接到我們的系統(tǒng)中,它被掛載到/media/BigDisk 目錄下,我們可以執(zhí)行一個有 用的系統(tǒng)備份了,首先在外部硬盤上創(chuàng)建一個目錄,名為/backup,然后使用 rsync 程序 從我們的系統(tǒng)中復(fù)制最重要的數(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)中復(fù)制到假想的存儲設(shè)備中。 我們包含了--delete 這個選項(xiàng),來刪除可能在備份設(shè)備中已經(jīng)存在但卻不再存在于源設(shè)備中的文件, (這與我們第一次創(chuàng)建備份無關(guān),但是會在隨后的復(fù)制操作中有用途)。掛載外部驅(qū)動器,運(yùn)行 rsync 命令,不斷重復(fù)這個過程,是一個不錯的(雖然不理想)方式來保存少量的系統(tǒng)備份文件。 當(dāng)然,別名會對這個操作更有幫助些。我們將會創(chuàng)建一個別名,并把它添加到.bashrc 文件中, 來提供這個特性:

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

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

在網(wǎng)絡(luò)間使用 rsync 命令

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

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

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

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

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

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

拓展閱讀

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

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

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