国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術文章
文章詳情頁

同步 UNIX 文件

瀏覽:3日期:2024-06-14 11:07:09

有許多工具可以用來跨 Unix® 目錄同步文件,但是要想有效且安全地完成這個任務,就需要多做一些工作。本文介紹跨 UNIX 文件系統和不同的計算機系統安全地同步文件的解決方案,包括如何為了執行備份同步文件的加密版本。

文件同步就是在一個位置添加、修改或刪除文件時,在另一個位置添加、修改或刪除同一個文件的過程。本文討論三個實用程序,cp、tar 和 rsync,它們都有助于同步 UNIX 文件。cp 和 tar 命令的同步功能有限,而 rsync 提供很全面的選項;盡管如此,它們都有各自適用的場合。

用 cp 命令執行直接復制

盡管 cp 命令并不是真正的同步命令,但它可能是在兩個位置之間復制文件的最簡單方法。對于單一文件復制,cp 顯然是非常高效的:$ cp source destination。

要想復制整個目錄結構,可以使用 -r 選項遞歸地把整個目錄結構從一個位置復制到另一個位置:$ cp -r source destination。這種復制方法僅僅遞歸地復制文件和目錄。文件的權限、所有者和其他元數據并不會復制到目標位置。可以使用 -p 選項保留復制的每個文件和目錄的所有者、權限和時間:$ cp -pr source destination。

使用 cp 命令是最容易最公認的文件復制方法,但是 cp 的效率很低,而且如果不使用 NFS 這樣的遠程文件系統解決方案,就不可能把目錄復制到遠程系統上。

使用 tar

tar(tape archive 的簡寫)實用程序原來用于高效地把目錄結構(包括文件和文件元數據)轉換為二進制流,然后就可以把二進制流寫到備份磁帶上。

通常使用 tar 創建一個包含所需目錄的 .tar 文件:$ tar cf mydir.tar ./mydir。c 選項讓 tar 創建新的存檔文件,f 選項使用后面的參數指定要創建的存檔文件的名稱 (mydir.tar)。其余參數指定應該包含在存檔文件中的文件或目錄。tar 命令自動地遞歸遍歷目錄結構,所以如果指定包含一個目錄,tar 將在存檔文件中包含這個目錄以及其中的所有文件和目錄。

tar 的一個重要特點是,用戶指定的路徑名被看作絕對路徑。也就是說,如果為 tar 指定完整的目錄位置,例如 /etc 目錄:$ tar cf etc.tar /etc。那么,在默認情況下,tar 將把文件提取到它們的絕對位置。例如,如果提取這個存檔文件:$ tar xf etc.tar,就會在 /etc 目錄中重新創建文件和目錄結構。這可能會產生破壞(可能會覆蓋 /etc 中希望保留的文件)。這個問題有兩種解決方法。第一種是使用 GNU tar,它支持通過 --strip-path 選項從提取的路徑中刪除元素。

另一個簡單的解決方法是進入父目錄,然后使用相對路徑(見清單 1)。

清單 1. 進入父目錄并使用相對路徑

 $ cd / $ tar cf etc.tar ./etc

在提取存檔文件時,會在相對位置重新創建文件。可以使用這種方法幫助同步目錄。因為 tar 創建目錄結構的字節流,可以通過結合使用 tar 和管道把文件從一個位置復制到另一個位置:$ tar cf - ./etc |( cd /backup; tar xf - )。“- 指定 tar 應該使用標準輸出(在寫時)或標準輸入(在讀時)。圓括號讓語句在一個子 shell 中執行。看一下管道符前面的代碼,它創建文件的字節流并發送到標準輸出。在管道符后面,切換到另一個目錄,然后從標準輸入提取字節流。

要想保留文件的所有者和權限,可以使用 p 選項保留每個文件和目錄的元數據:$ tar cfp - ./etc |( cd /backup; tar xfp - )。

掌握這種基本結構之后,就可以執行更復雜的操作。例如,可以只復制在特定時間之后修改過的文件:$ tar cf - --newer 20090101 ./etc |(cd /backup; tar xf - )。這個命令創建在 2009 年 1 月 1 日之后修改過的文件的拷貝。

通過與 rsh 或 ssh 結合使用,還可以把文件同步到遠程主機:$ tar cfp - ./etc |(ssh user@host -- tar xfp -)。按照這種方式使用 ssh 和 tar 是在遠程主機上創建本地文件備份的好方法。但是,還有更高效的信息同步方法。

使用 rsync 進行智能化同步

前面介紹的文件同步方法的主要問題是,它們會復制每個文件(和相關聯的目錄結構)。如果您打算創建信息的新拷貝,這就沒關系;但是,如果要同步兩個目錄中的信息,這種方法的效率很低。

假設一個目錄中有 10,000 個文件,它們占用 100GB 的空間。如果修改了一個 10MB 的文件,在使用 cp 或 tar 進行同步時,就必須重新復制所有 100GB 文件。對于備份,復制如此大量的信息是很過分的。我們希望盡可能快速有效地完成備份。顯然,如果知道哪些文件修改過了,就可以只復制這些文件,但是不總是能夠知道這一信息。

tar 的 --newer 選項的作用是有限的,因為必須知道上一次修改的準確時間。rsync 工具能夠解決這個問題。它會比較目錄結構和各個文件,判斷源目錄和目標目錄之間的差異。在查明哪些文件和目錄已經修改了之后,它只把這些文件和目錄復制到目標位置。另外,rsync 對各個文件使用相似的算法,只復制文件中修改過的部分。

按照最簡單的形式,可以使用 rsync 把一個目錄同步到一個新目錄,例如:$ rsync -r a b。這會創建新目錄 b,其中包含目錄 a 中目錄結構的拷貝。-r 選項讓 rsync 遞歸遍歷目錄并復制整個目錄結構。但是,如果目標目錄已經存在,就會在目標目錄 b 中創建一個新目錄 a,其中包含文件的拷貝。這會有一些糟糕的副作用。例如,如果要把多個目錄復制到備份目錄,就會像清單 2 這樣做。

清單 2. 把多個目錄復制到備份目錄

 $ mkdir backup $ rsync dira backup $ rsync dirb backup

清單 2 創建目錄 backup/dira,其中包含原來 dira 目錄的拷貝。它還創建目錄 backup/dirb,其中包含原來 dirb 目錄的拷貝。后面的情況就不一樣了:$ rsync dira backup/dira。在第一次使用時,這個腳本的作用符合期望。但是,在第二次使用時,rsync 會在指定的目標目錄中創建目標目錄,也就是創建 backup/dira/dira 目錄。這不僅沒有創建我們需要的結構,還造成了內容重復(其中一個版本是沒有同步的)。

在使用 rsync 時,可能需要指定另外幾個選項。默認的同步并不復制文件元數據,而且像對待普通文件那樣對待某些特殊文件(比如鏈接)。希望使用的主要選項包括:

●--delete —— 從目標目錄中刪除源目錄中不再存在的文件。默認模式僅僅同步文件修改并創建新文件。在默認情況下,如果在源目錄中刪除了一個文件,就會忽略它,并不在目標目錄中相應地刪除它。通過使用這個選項,可以創建完全相同的同步。

●--recursive —— 遞歸地復制目錄和文件。

●--times —— 同步每個文件和目錄的修改時間和創建時間。

●--owner —— 如果可能的話,保留文件的所有者。

●--group —— 如果可能的話,保留組所有者。

●--links —— 把符號鏈接復制為符號鏈接,而不是復制文件數據并解釋源鏈接。

●--perms —— 保留文件權限。

●--hard-links —— 保留硬鏈接(在目標目錄中創建硬鏈接),而不是復制文件內容。

其中一部分選項只能在兩個系統的配置完全相同的情況下使用。例如,只有在源和目標計算機對相同用戶使用相同 ID 的情況下,才能保留文件所有者和組所有者設置。

除了本地復制之外,rsync 還可以使用 ssh 執行遠程復制。為此,需要在源目錄或目標目錄前面指定用戶名和遠程主機。例如,為了把一個目錄同步到遠程系統 user 上,執行以下命令:$ rsync --recursive dira user@remote:/backup/dirb。如果沒有設置無密碼 ssh 連接,那么會提示您輸入遠程密碼。如果已經設置了連接,就可以用這種方法執行無人值守的夜間備份。

還可以對源目錄使用相同的用戶/密碼組合,從而從遠程源目錄復制到本地目錄:$ rsync --recursive user@remote:dira dirb。在通過 Internet 復制到遠程系統時,還可以使用 --compress 選項在通過網絡傳輸信息之前壓縮信息,與原始字節復制相比,這可以大大提高效率。當然,在復制到遠程系統時,如果文件包含敏感信息,可能不希望復制原始文件。在這種情況下,就需要使用加密。

加密同步涉及的文件

使用文件同步解決方案的常見原因之一是,為了創建文件的精確備份,以便在出現問題時能夠復制或重建目錄結構的元素。

rsync 工具非常適合完成這個任務,因為它只復制兩個目錄之間有差異的文件,效率很高。更有意義的是,因為 rsync 可以同步到遠程系統,所以可以使用它自動創建遠程備份,不需要把備份文件單獨復制到遠程系統。

這個過程的一個限制是,創建的拷貝是未加密的。如果要把文件復制到遠程系統,而其他人也能夠訪問這個遠程系統,就需要確保其他人無法讀取這些文件(即使他們能夠接觸到這些文件)。

只使用 rsync 是無法加密文件的。也無法使用 rsync 的算法只加密在上一次同步操作之后修改過的文件。

但是,通過在腳本中執行 rsync,就可以用 rsync 的輸出創建文件的輔助拷貝,然后對這個拷貝進行加密。

這個腳本的基本原理是創建原目錄結構的兩個拷貝。第一個拷貝作為參照拷貝,其中包含目錄結構的精確副本。這樣,當再次同步目錄時,就可以像一般情況一樣比較源和目標文件并判斷出差異。在 rsync 命令中使用 --itemize-changes 選項,rsync 就會創建一個參照列表,其中列出在同步期間每個文件所發生的情況。輸出詳細說明文件是否已經修改過(或新建),或文件是否已經刪除。清單 3 中給出一個示例。

清單 3. rsync 生成的修改記錄

 .d..t...... t1/a/ *deleting t1/a/3 .d..t...... t1/b/ >f.st...... t1/b/1 >f+++++++++ t1/b/6  

以 .d. 開頭的行表示新目錄或目錄修改。*deleting 行表示文件已經從源目錄中刪除。>f 行表示文件已經修改過或是新建的文件(>f++++++++)。

通過解析這個輸出文件,可以判斷出源目錄和目標參照目錄之間的差異。判斷出差異之后,可以在第三個目錄中創建原文件的加密版本。通過使用修改記錄,只加密(或刪除)在上一次同步操作之后修改過的文件。不能使用目錄的加密版本直接執行同步,因為文件的加密版本總是與源文件不一樣。

完整的腳本見清單 4。

清單 4. 完整腳本

 #!/usr/bin/perl use warnings; use strict; use File::Basename; use File::Path; my $source = shift; my $dest = shift; my $encdest = shift; if (!defined($source) || !defined($dest) || !defined($encdest)) {   print "Error: Not enough arguments!n";   print "Usage: $0 source destination encrypteddestn";   exit(1); } print STDERR "Running rsync between $source and $dest ($encdest)n"; system("rsync --delete --recursive --times -og --links --perms " . "--hard-links --itemize-changes $source $dest " . ">/tmp/$$.rsynclog 2>&1"); open(DATA,"/tmp/$$.rsynclog") or dIE "Couldn't open the rsynclogn"; my @changedfiles; my @delfiles; while(<DATA>) {   next if (m/sending incremental file list/);   chomp;   last if (length($_) == 0);   my ($changes,$filename) = split;   push @changedfiles,$filename if ($changes =~ m/^>f/);   push @delfiles,$filename if ($changes =~ m/^*del/); } close(DATA); my $counter = 0; foreach my $file (@changedfiles) {   if (-f "$dest/$file")   {   my $sourcename = encode_filename("$dest/$file");   my $destname = encode_filename("$encdest/$file");   my $dirname  = dirname("$encdest/$file");   mkpath($dirname);   system(sprintf('cat "%s" |openssl enc -des3 ' . '-pass file:/var/lib/passphrase -a >"%s"', $sourcename,$destname));   $counter++;   } } my $delcounter = 0; foreach my $file (@delfiles) {   unlink("$encdest/$file");   $delcounter++; } print STDERR "Finished (changed: $counter, deleted: $delcounter)n"; unlink("/tmp/$$.rsynclog"); sub encode_filename {   my ($filename) = @_;   $filename =~ s/ / /g;   $filename =~ s/'/'/g;   $filename =~ s/"/"/g;   $filename =~ s/(/(/g;   $filename =~ s/)/)/g;   $filename =~ s/&/&/g;   $filename =~ s/#/#/g;   return($filename); }  

這個腳本非常簡單,很容易使用。在運行腳本時,指定源目錄、參照文件的目標目錄和文件加密版本的目標目錄:$ rsyncrypt source destination destination.enc。

腳本的第一部分在源和目標目錄之間執行基本的同步以判斷修改(見清單 5)。這個操作生成記錄修改的文件(在 /tmp 目錄中)。

清單 5. 在源和目標目錄之間執行基本的同步

 system("rsync --delete --recursive --times -og --links --perms " . "--hard-links --itemize-changes $source $dest " . ">/tmp/$$.rsynclog 2>&1");  

接下來,解析修改的列表,生成已經修改和刪除的文件的列表(見清單 6)。

清單 6. 解析修改的列表

 while(<DATA>) {   next if (m/sending incremental file list/);   chomp;   last if (length($_) == 0);   my ($changes,$filename) = split;   push @changedfiles,$filename if ($changes =~ m/^>f/);   push @delfiles,$filename if ($changes =~ m/^*del/); }  

對于每個修改過的文件,讀取參照版本并在加密目標目錄中創建加密版本(見清單 7)。

清單 7. 創建每個修改過的文件的加密版本

 foreach my $file (@changedfiles) {   if (-f "$dest/$file")   {   my $sourcename = encode_filename("$dest/$file");   my $destname = encode_filename("$encdest/$file");   my $dirname  = dirname("$encdest/$file");   mkpath($dirname);   system(sprintf('cat "%s" |openssl enc -des3 ' . '-pass file:/var/lib/passphrase -a >"%s"', $sourcename,$destname));   $counter++;   } }  

因為要使用 shell 執行實際的加密,文件名必須進行編碼。需要對一些特殊字符進行轉義,否則 shell 會解釋它們。

對于實際的加密,使用 openssl 和一個簡單的文本文件(在 /var/lib/passphrase 中),這個文件包含信息編碼所用的密碼。還可以創建或使用專門生成的密鑰來執行此操作或希望使用的其他加密命令。

最后,因為源目錄中可能有已經刪除的文件,還要把刪除的文件從加密目錄內容中刪除(見清單 8)。

清單 8. 把刪除的文件從加密目錄內容中刪除

 foreach my $file (@delfiles) {   unlink("$encdest/$file");   $delcounter++; }  

這個腳本非常有效,惟一的缺點是它需要信息的兩個拷貝(參照目錄和加密版本),而不只是一個。另外,為了簡化這個過程,并沒有把權限、所有者和時間戳信息同步到加密版本,但是很容易添加這個特性。因為這個腳本使用 rsync 生成修改的列表,這會顯著減少需要加密的文件數量,可以使用相同的優化算法把新的文件加密版本同步到遠程主機,從而只傳輸在上一次同步操作之后修改過的加密文件。

結束語

本文討論了幾種不同的文件同步方法。基本的 cp 命令并不是真正的同步命令,但是可以用來執行直接復制。對于真正的同步操作,cp 命令花費的時間太長,效率很低。在使用 tar 時,可以指定一個時間參照點,只復制在這個時間點之后修改過的文件。但是,如果修改不明顯或無法通過簡單的比較查明,這個特性的意義也不大。

rsync 工具是更好的文件同步解決方案。它對源和目標目錄執行許多檢查和比較,可以實現高效的同步,甚至可以通過網絡或公共連接執行同步。為了確保安全,可以結合使用 rsync 與加密技術,確保在沒有正確的密碼或加密密鑰的情況下無法讀取遠程文件。

標簽: Unix系統
主站蜘蛛池模板: 亚洲精品久久99久久一区 | 久久精品亚瑟全部免费观看 | 精品日韩在线视频一区二区三区 | 97精品国产综合久久久久久欧美 | 黄色片亚洲 | 久久国产精品久久国产片 | 国产免费v片在线看 | 国产高清精品在线 | 日本一极毛片兔费看 | 精品在线观看国产 | 香蕉依依精品视频在线播放 | 91久久综合 | 99精品视频在线视频免费观看 | 欧美一区三区 | 欧美高清一级 | 日韩一级黄色 | 欧美视频一区二区专区 | 在线视频久| 久久免费看 | 免费在线视频成人 | 免费v片在线观看 | 免费一级美国片在线观看 | 亚洲视频aaa | 久久久久久亚洲精品 | 亚洲人成在线免费观看 | 亚洲欧美天堂 | 久久偷看各类wc女厕 | 亚洲国产二区三区 | 欧美午夜免费毛片a级 | a级片在线 | 欧美日韩a∨毛片一区 | 亚洲综合成人网 | 国产在线精品一区二区夜色 | 国产成年网站v片在线观看 国产成人aa在线视频 | 精品视自拍视频在线观看 | 交视频在线观看国产网站 | 寂寞午夜影院 | 九九九免费视频 | 亚洲国产精品一区二区三区 | 视频二区国产 | 日本二区免费一片黄2019 |