對話 UNIX,第 5 部分: 操縱數(shù)據(jù)與文件
近些年來,計算機(jī)硬件變得非常的便宜。每 GB 的硬盤空間只需要 0.50 美元,一臺 19 英寸的平板顯示器售價還不到 200 美元,一臺可以運行 Unix® 的便攜式電腦售價還不到 1000 美元。即使是專門的服務(wù)器硬件也不是很昂貴。
價格如此的便宜,使得一個中型或大型的組織可以為不同的任務(wù)采用單獨的硬件設(shè)備。而且,只需要將計算機(jī)連接到網(wǎng)絡(luò)、將磁盤映像復(fù)制到一臺普通的計算機(jī)并重新啟動,就可以輕松地擴(kuò)展計算能力。當(dāng)然,沒有免費的午餐。每臺計算機(jī)都需要電能、空調(diào)以及關(guān)心和愛護(hù)。
在管理大量的計算機(jī)時最常見的問題之一是,如何保持這些系統(tǒng)最新和一致。在有些情況下,您希望在所有的地方都部署某個應(yīng)用程序的相同版本,以免不一致的特性讓用戶感到困惑。或者,作為另一個示例,您可能希望在用于相同目的的不同服務(wù)器中安裝相同的操作系統(tǒng)。具有可預(yù)測性是很有好處的。
即使您只擁有一臺便攜式計算機(jī)和一臺臺式計算機(jī),保持這兩臺計算機(jī)之間的同步也可能是一項艱巨的任務(wù)。今天,您正在使用便攜式計算機(jī)進(jìn)行工作。而昨天,您可能使用臺式計算機(jī)對某些內(nèi)容進(jìn)行了修改。您可能在這兩天中都向中央文件服務(wù)器上傳或從中下載了一些文件。隨著數(shù)據(jù)的上傳和下載,很快您就會被什么數(shù)據(jù)放在什么地方給弄糊涂。
在本系列的第 5 部分中,讓我們來討論一些有價值的技術(shù),它們可以幫助您控制文件數(shù)目急劇增加的局面。
壓縮和轉(zhuǎn)發(fā)
很顯然,要在多臺不同的計算機(jī)之間維護(hù)數(shù)據(jù)的一致性,最簡單的方法是隨身攜帶您的文件(電子表格、數(shù)據(jù)庫、文本文件,等等)。如果您可以直接接觸到所使用的每臺計算機(jī),那么您可以攜帶一個便攜式磁盤、CD-RW 或大容量的便攜閃存,并在需要使用這些文件時插入存儲設(shè)備。
然而,如果您所使用的計算機(jī)是遠(yuǎn)程的或無法直接接觸到的,假設(shè)在愛達(dá)荷州 Boise 的機(jī)房中,無法直接連接外部設(shè)備。相反,您可以為您的(一些或所有的)文件建立存檔,連接到局域網(wǎng) (LAN) 或廣域網(wǎng) (WAN) 中,將存檔復(fù)制到目標(biāo),然后恢復(fù)這些文件以便繼續(xù)工作(而且,您可以使用存檔作為簡單的備份,以便在出現(xiàn)災(zāi)難的情況下保護(hù)您的文件,比如將計算機(jī)忘在出租車中)。
在 Unix 系統(tǒng)中,可靠的實用程序 tar 可以用來簡化構(gòu)建存檔的工作。tar 實用程序?qū)⒁粋€或多個文件和目錄打包為單個文件,并保持原始文件的大小、擁有者、權(quán)限、文件類型及其在文件系統(tǒng)層次結(jié)構(gòu)中的位置。tar 實用程序?qū)⒛奈募暾赜涗浀酱艓е校瑃ar 是磁帶存檔程序 (tape archiver) 的首字母縮寫。
例如,假設(shè)您在一個目錄中放入了各種各樣的文件,如清單 1 所示。
清單 1. 文件目錄
$ cd stuff$ ls -lR.:drwxr-xr-x 2 mstreicher mstreicher 4096 Oct 12 19:11 CSS-rwxr-xr-x 1 mstreicher mstreicher 91 Aug 17 2005 demo.rb-rw-r--r-- 1 mstreicher mstreicher 111563 Oct 12 19:10 tech.pdf./css:total 16-rw-r--r-- 1 mstreicher mstreicher 711 Mar 25 2006 style.css-rw-r--r-- 1 mstreicher mstreicher 11353 Apr 10 2006 valid.css
要為這兩個文件和一個目錄創(chuàng)建存檔,可以運行下面的 tar 命令:
$ tar --create --verbose --gzip --file archive.tgz *css/css/style.csscss/valid.cssdemo.rbtech.pdf
--create 選項告訴 tar 創(chuàng)建一個存檔;--verbose 選項為 tar 所處理的文件生成一個列表;--gzip 選項啟用 gzip 方式的壓縮,這將縮小該存檔的大小;而 --file archive.tgz 指定了存檔的名稱。
Shell 將星號 (*) 解釋為“任何文件,所以對其展開后為兩個文件和一個目錄。從上面的輸出中您可以看出,tar 對 CSS 目錄進(jìn)行了存檔,同時遞歸地對該目錄中的內(nèi)容進(jìn)行了存檔。
在運行 tar 命令之后,當(dāng)前目錄中包含了一個新的文件 archive.tgz:
$ ls -l archive.tgz-rw-r--r-- 1 mstreicher mstreicher 105470 Oct 13 17:16 archive.tgz
現(xiàn)在,您可以將 archive.tgz 復(fù)制到另一臺計算機(jī),并在遠(yuǎn)程計算機(jī)上使用 tar 解壓存檔的內(nèi)容。事實上,用來恢復(fù)文件的命令行與前面使用的命令行基本相同。要對這個存檔進(jìn)行解壓,可以使用:
$ tar --extract --verbose --gunzip --preserve-permissions --file archive.tgz
這個 tar 命令將解壓 archive.tgz 壓縮文件中的內(nèi)容。--extract 選項與 --create 選項正好相反;--gunzip 與 --gzip 相反,而 --preserve-permissions 將重新創(chuàng)建原始文件的權(quán)限。
在運行了這個命令之后,完整地恢復(fù)了所保存的文件,并保持了原來的時間戳、權(quán)限和文件名。同時,重新創(chuàng)建了名為 css 的目錄,并將其中的內(nèi)容壓縮到了最初的位置。
tar 實用程序具有許多選項:--create、--extract 和 --list(列出 .tar 文件的內(nèi)容而不展開該文件)。其他的選項(如 --gzip 和 --preserve-permissions)用來控制 tar 如何創(chuàng)建存檔。有關(guān)在您的 Unix 版本中每個選項更詳細(xì)的信息和正確的語法,請參閱 tar 的 man 頁面。
創(chuàng)建存檔、將其復(fù)制到目標(biāo)、然后再解壓縮,這種方法非常有用,但是可能比較費事。另外,如果存檔非常大,您可能無法同時存儲存檔和解壓后的文件。如果源和目標(biāo)計算機(jī)之間通過 LAN 或 WAN 連接,那么為了節(jié)省時間,您可以組合使用 Secure Shell (SSH) 和 tar 命令,以將文件存檔、復(fù)制和解壓合并為一步操作。下面是完成這項工作的命令:
$ (cd ~/stuff; tar --create --gzip --file - *) | ssh destination tar --extract --gunzip --file --verbose -C stuff
該命令進(jìn)行了很多操作,所以讓我們對其進(jìn)行分解:
命令中帶圓括號的部分稱為subshell。subshell 中進(jìn)行的更改,例如更改目錄,不會影響到您的命令行,但是它將影響 subshell 的執(zhí)行環(huán)境。因此,第一個短語 (cd ~/stuff; tar --create --gzip --file - *) 更改到目錄 ~/stuff,然后運行 tar。因為 subshell 后面跟著管道,所以 subshell 的所有輸出都通過管道傳輸給了下一個命令。
與許多其他的 Unix 實用程序一樣,tar 可以分別向標(biāo)準(zhǔn)輸出 (stdout) 寫入、從標(biāo)準(zhǔn)輸入 (stdin) 讀取。stdout 和 stdin 通常表示為連字符 (-)。所以,短語 --create --file - 在 stdout 上創(chuàng)建存檔。
管道 (|) 將 subshell 的所有輸出通過管道傳輸給 ssh。這樣可以有效地將所有的輸出從源計算機(jī)傳輸?shù)侥繕?biāo)計算機(jī)。
最后,目標(biāo)計算機(jī)運行自己的 tar 實例對存檔進(jìn)行解壓。然而,這里的 --extract --file - 從標(biāo)準(zhǔn)輸入 讀取存檔。-C 選項強(qiáng)迫接收方 的 tar 在開始進(jìn)行任何處理之前,將目錄更改到 stuff(在遠(yuǎn)程 home 目錄中)。最后的結(jié)果是,將通過 ssh 傳輸?shù)拇鏅n解壓到 ~/stuff 中。
通過這一個(有些冗長的)命令,您創(chuàng)建了、傳輸并解壓縮了存檔。順便提一下,對該命令行中內(nèi)容的順序稍作顛倒,您就可以從遠(yuǎn)程計算機(jī)中獲取創(chuàng)建的存檔并解壓到本地計算機(jī)。下面的命令可以實現(xiàn)這項任務(wù),在本地計算機(jī)中運行:
$ ssh destination cat archive.tgz | (cd ~/stuff; tar --extract --gunzip --file -)
在遠(yuǎn)程計算機(jī)上打開遠(yuǎn)程存檔,將 cat 產(chǎn)生的字節(jié)流發(fā)送到 subshell,這個 subshell 首先更改目錄,然后對存檔進(jìn)行解壓縮。(為 tar 命令添加 -C ~/stuff 可以起到與前面相同的作用;這個示例顯示了 subshell 也可以使用輸入。)
您可以使用相同的方法在同一臺計算機(jī)上對文件進(jìn)行鏡像。嘗試下面的命令:
tar --create --file - * | tar -C /path/to/Directory --extract --file -
通過復(fù)制方式存檔
tar 實用程序加上 ssh,可以很方便地將文件從一臺計算機(jī)傳輸?shù)搅硪慌_計算機(jī)。tar 實用程序創(chuàng)建存檔,而 ssh 則實現(xiàn)該存檔的安全傳輸。
另一種方法是使用 SSH 固有的能力將文件從一臺計算機(jī)傳輸?shù)搅硪慌_計算機(jī)。sftp 是 SSH 的另一種特征,它提供了文件傳輸協(xié)議 (FTP) 的所有特性,并且在傳輸?shù)倪^程中對文件數(shù)據(jù)進(jìn)行保護(hù)。(通常,不建議使用 FTP,因為它不是很安全,然而公共的 FTP 站點是個例外。)
如果您曾經(jīng)使用過 FTP,sftp 實際上與其相同。只需輸入 sftp destination 以連接到名為 destination 的遠(yuǎn)程計算機(jī),然后運行 FTP 命令,如 cd、lcd、mput 和 mget 以便對文件進(jìn)行雙向移動。
在兩臺計算機(jī)之間傳輸文件的另一種方法是使用 scp,即安全復(fù)制 (secure copy)。顧名思義,scp 的工作方式與普通的 cp 非常相似,它可以用來將文件從一個地方復(fù)制到另一個地方,可以在同一臺計算機(jī)上或兩臺不同的計算機(jī)之間。
例如,如果您希望在本地計算機(jī)中將一些文件和目錄復(fù)制到另一個目錄,您可以運行與清單 2 中所示類似的代碼。
清單 2. 在兩臺計算機(jī)之間復(fù)制文件
$ ls -lFdrwxr-xr-x 2 mstreicher mstreicher 4096 Oct 12 19:11 CSS/-rwxr-xr-x 1 mstreicher mstreicher 91 Aug 17 2005 demo.rb*-rw-r--r-- 1 mstreicher mstreicher 111563 Oct 12 19:10 tech.pdf$ cp -pr * /home/joe/stuff$ ls -lF /home/joe/stuffdrwxr-xr-x 2 mstreicher mstreicher 4096 Oct 12 19:11 css/-rwxr-xr-x 1 mstreicher mstreicher 91 Aug 17 2005 demo.rb*-rw-r--r-- 1 mstreicher mstreicher 111563 Oct 12 19:10 tech.pdf
在這個示例中,cp -pr 遞歸地將所有的文件和目錄復(fù)制到 /home/joe/stuff。-r 表示遞歸;-p 表示保持該文件的時間戳。
您可以使用 scp 完成相同的工作(即在本地進(jìn)行復(fù)制):
$ scp -pr * /home/joe/stuff
但如果您指定了遠(yuǎn)程系統(tǒng),那么 scp 可以通過網(wǎng)絡(luò)復(fù)制文件:
$ scp -pr * destination:/home/joe/stuff
假定目標(biāo)計算機(jī)中存在 /home/joe/stuff 目錄,并且對您來說是可寫的,那么這兩個文件和一個目錄將完整地復(fù)制到遠(yuǎn)程計算機(jī)。與 cp 一樣,scp 使用 -p 表示保持文件的時間戳,-r 表示遞歸。
scp 很容易使用,特別是當(dāng)建立了私-公鑰對時,可以避免在每次執(zhí)行 ssh/scp/sftp 操作時輸入密碼。
然而對于 scp,有一個特殊的問題需要注意。假定您在自己的 home 目錄中有一個名為 doc 的目錄,并且您希望將其復(fù)制到遠(yuǎn)程系統(tǒng)。而且,您希望當(dāng)文件或目錄具有相同名稱時,使用 ~/doc 中的內(nèi)容替換遠(yuǎn)程 doc 目錄中的內(nèi)容。需要使用的命令應(yīng)該與下面所示類似:
$ scp -pr ~/doc destination:/path/to/doc
請注意,目標(biāo)計算機(jī)上的目錄沒有尾部的斜杠 (/)。scp 將這個路徑解釋為“將 ~/doc 目錄中的內(nèi)容復(fù)制到目標(biāo)計算機(jī)的 /path/to/doc 目錄。與 cp 一樣,與本地文件和目錄具有相同名稱的遠(yuǎn)程文件和目錄將被覆蓋,而遠(yuǎn)程系統(tǒng)中所特有的文件將保持不變。
然而,如果您添加上尾部的斜杠,如下所示:
$ scp -pr ~/doc destination:/path/to/doc/
scp 將后面的這個路徑解釋為“將 ~/doc 目錄復(fù)制到 /path/to/doc/ 目錄。所以,將本地 doc 目錄復(fù)制到遠(yuǎn)程目錄中,而不是覆蓋遠(yuǎn)程目錄的內(nèi)容。
尾部的斜杠并不是一個錯誤。有時您可能希望使用它,而有時您可能不希望使用它,這取決于實際情況。
保持同步
scp 非常有用,因為它與 cp 非常接近。tar 和 ssh 稍微復(fù)雜一點,但它們可以保持文件的元數(shù)據(jù),如擁有者和權(quán)限。
但是 tar 和 scp 都無法對本地和遠(yuǎn)程目錄中的內(nèi)容進(jìn)行同步。例如,如果您在本地系統(tǒng)中更改了一個文件,并在遠(yuǎn)程系統(tǒng)中更改了另一個文件,那么為了建立工作鏡像,您不得不運行兩次 scp 命令。現(xiàn)在可以想象一下,如果您更改了大量的文件,并且其中許多具有相同的名稱,很快地,您將會發(fā)現(xiàn)同步工作變得非常復(fù)雜。
幸運的是,有一個名為 rsync 的神奇的實用程序,它可以對文件集進(jìn)行同步。然而更有價值的是,rsync 僅對那些更改過的數(shù)據(jù)進(jìn)行傳輸,這樣可以使得傳輸?shù)臄?shù)據(jù)量最小化。
與 tar 一樣,您可以將 rsync 與 ssh 組合使用,以連接到遠(yuǎn)程系統(tǒng)并對本地和遠(yuǎn)程的文件集合進(jìn)行同步。與 scp 一樣,您可以使用 rsync 在本地進(jìn)行文件復(fù)制。您還可以使用 rsync 列舉文件。
其最大的優(yōu)點在于,rsync 具有各種選項,要使得一個目錄成為另一個目錄真正的鏡像,可以使用相應(yīng)的選項刪除原始目錄中不存在的那些文件。讓我們來看一些示例:
$ rsync -e ssh --times *.txt destination:
這個命令將當(dāng)前工作目錄中所有的文本文件復(fù)制到您在名為 destination 的計算機(jī)上的 home 目錄中。-times 選項保持每個文件的訪問權(quán)限、創(chuàng)建和最后修改時間。
$ rsync -e ssh --times --perms --recursive --delete doc destination:
這個變化的 rsync 命令在目標(biāo)計算機(jī)上您的 home 目錄中創(chuàng)建本地 doc 目錄的鏡像。同時保持文件的時間和權(quán)限,并且刪除外來的文件(即,在本地目錄中不存在的遠(yuǎn)程目錄中的文件)。
因為 rsync 可能執(zhí)行一些重要的更改,所以您可能希望為該命令行添加 --dry-run 選項,以便預(yù)覽 rsync 計劃完成哪些操作。--dry-run 并不進(jìn)行任何更改,它僅僅顯示將要執(zhí)行的操作,如下面的清單 3 所示。
清單 3. 預(yù)覽 rsync 將要執(zhí)行的操作
$ rsync -e ssh --dry-run --times --perms --recursive --delete bin destination:building file list ... donebin/skipping non-regular file "bin/HTML.pl"skipping non-regular file "bin/Quark.pl"bin/Responses/bin/Responses/DBI.pmbin/Responses/Response.pmskipping non-regular file "bin/XML.pl"bin/backupdca.shbin/lib/bin/report.plbin/report.txtsent 724 bytes received 108 bytes 554.67 bytes/sectotal size is 168879 speedup is 202.98
rsync 具有許多選項:
-a 是非常有用的選項,因為它是 --group --owner --perms --times --devices --links --recursive 的縮寫。--devices 重新創(chuàng)建設(shè)備文件,而 --links 將符號鏈接復(fù)制為符號鏈接,而不是復(fù)制符號鏈接所指向的內(nèi)容。
--update 可以防止 rsync 覆蓋較新的文件。如果遠(yuǎn)程系統(tǒng)具有比本地系統(tǒng)較新的文件,那么將會保留遠(yuǎn)程系統(tǒng)中的這個文件。
可以嘗試使用 --verbose 選項,以便在 rsync 命令執(zhí)行的過程中進(jìn)行觀察。
同樣的,有關(guān) rsync 的更多使用技巧,請閱讀 man 頁面。它具有一種重要的特性,即您可以定義需要包括和排除的文件。
數(shù)據(jù)無處不在
Unix 已在網(wǎng)絡(luò)環(huán)境中使用了 20 多年。其間,硬件發(fā)生了很大的變化,而大部分軟件則保持不變,這為用戶和系統(tǒng)管理員帶來了困難。最大的問題之一是,隨著磁盤的容量變得越來越大,要想跟蹤所有的數(shù)據(jù)更加困難。這些實用程序,如 tar、sftp/scp 和 rsync 可以用來完成各種磁盤操作。
本系列的第 6 部分將討論自動化方面的內(nèi)容,這是另一種節(jié)省時間和精力并減少人工錯誤的方法。
相關(guān)文章:
