15.5 安全传输和备份文件

rsync -v

rsync是最酷、最有用的命令之一,很多人每天都要依赖它(就像我一样)。它是干什么的呢?它的用途多得数不清(这里再说一遍“关于这个命令可以写本书!”),但本书主要介绍一个非常强大、必需的功能:有效而安全地备份文件,同时付出最少的网络流量。

假设需要在每天半夜从名为coleridge的计算机上(用户名为sam)将2 GB的文件备份至一台名为wordsworth的计算机上(用户名为will)。如果没有rsync,每天夜里你就会看到这2 GB文件的传输,即使是在连接速度很快的网络中,这也是不小的数据传输量。不过,有了rsync,这一传输一小会儿就可以完成。为什么呢?因为在rsync备份这2 GB的文件时,它只传输所有2 GB数据的文件中发生过变化的那些文件。如果在过去的24小时内只有几百KB字节的数据发生了变化,那么这就是rsync命令所有要传输的内容。如果发生变化的数据有100 MB,rsync命令也只复制这100 MB的数据。不管在什么情况下,复制的数据量会大大少于2 GB。

这个命令是这样来用的,从coleridge计算机上运行,将documents目录的所有内容传输到wordsworth计算机的一个备份驱动器上。先看看这个命令和它的运行结果,接着仔细研究一些选项的含意[为了可读性,第一个命令使用了长选项格式,而不是单个字符;第二个命令的选项则使用了单个字符(如果有可用的短选项),以便比较],如下所示:

  1. $ rsync --verbose --progress --stats recursive
  2. ➥--times --perms --links --compress --rsh=ssh
  3. ➥--delete /home/sam/documents/
  4. will@wordsworth:/media/backup/documents
  5. $ rsync -v --progress --stats -r -t -p -l -z -e ssh
  6. ➥--delete /home/sam/documents/
  7. will@wordsworth:/media/backup/documents

当然,如果想把所有选项组合起来的话,也可以按如下方式运行命令:

  1. $ rsync -vrtplze ssh --progress --stats delete
  2. ➥/home/sam/documents/will@wordsworth:/media/backup/documents

在使用以上列出的任何一种方法运行rsync命令以后,将看到类似以下内容的输出:

  1. building file list ...
  2. 107805 files to consider
  3. deleting clientele/Linux_Magazine/do_it_yourself/13/
  4. gantt_chart.txt~
  5. deleting Security/diebold_voting/black_box_voting/
  6. bbv_chapter-9.pdf
  7. deleting E-commerce/Books/20050811 eBay LIL ABNER
  8. DAILIES 6 1940.txt
  9. Security/electronic_voting/diebold/black_box_voting/
  10. bbv_chapter-9.pdf
  11. legal_issues/free_speech/Timeline A history of free speech.txt
  12. E-commerce/2005/Books/20050811 eBay LIL ABNER DAILIES 6 1940.txt
  13. connectivity/connectivity_info.txt
  14. [Results greatly truncated for length]
  15. Number of files: 107805
  16. Number of files transferred: 120
  17. Total file size: 6702042249 bytes
  18. Total transferred file size: 15337159 bytes
  19. File list size: 2344115
  20. Total bytes sent: 2345101
  21. Total bytes received: 986
  22. sent 2345101 bytes received 986 bytes 7507.48 bytes/sec
  23. total size is 6702042249 speedup is 2856.69

先看一下这些结果。rsync命令先构建一个它必须要考虑的所有文件的列表(在这个例子中是107 805个文件),接着删除任何在目标位置(wordsworth)已经存在,但在源位置(coleridge)已经不存在的文件。在本例中,删除了3个文件:来自Linux Magazine的一篇文章的备份文件(~是一个附加的字符)、一个关于电子投票的PDF文件及一个购买过的图书的文本收据。

删除完文件以后,rsync就开始复制所有发生过变化的文件,或者如果是同一个文件,但文件的部分内容有变化,rsync会只复制这个文件中发生变化的部分。在本例中,复制了4个文件。结果,那个PDF文件实际上是被移动到了一个新的子目录中,但对于rsync来说,它还是个新文件,所以要完整复制它。

文本收据文件也是如此。“A history of free speech.txt”这个文件是个全新的文件,所以也直接将它复制到wordsworth 。

在列出进行的变化之后,rsync会给出一些有关传输的总体信息。总共传输了120个文件,6702042249 字节(大约6.4 GB)中传输了15337159字节(大约14 MB)。在统计中还包含一些其他数据,但以上的信息是关键数据。

现在看看向计算机发出的命令。命令的首部和尾部比较容易理解:命令以rsync作为开始,后面跟着选项,接着是复制文件的源目录(coleridge计算机上的/home/sam/documents/),随后是复制文件的目标目录(wordsworth计算机上的/media/backup/documents)。在介绍各个选项之前,先重点看看源目录和目标目录的指定方式,这里需要理解清楚,否则会造成实际的损害。

想复制的是coleridgedocuments目录中的内容,但不包括目录本身,所以源目录应该使用documents/,而不是documents。在/home/sam/documents/中,documents后面的斜线(“/”字符)是在告诉rsync命令:想把那个目录的“内容”复制到wordsworth上的documents目录中;如果只用documentsrsync命令复制的就是目录及其内容,结果是将源目录复制到了wordsworth计算机上的/media/backup/documents/documents这个目录中。

说明 斜线只在源目录中重要,在目标目录中是否使用斜线则无关紧要。

有个选项在前面的例子中没有使用,但是当想先估计一下rsync命令将如何构建备份过程时,使用这个选项是个好主意:-n(或--dry-run)。如果命令中包含了这个选项,在rsync运行时,它并不会真正地删除或复制任何东西。如果你的选择可能会导致删除重要的文件,这个选项就是救命的稻草了。在提交rsync命令以前,尤其是当包括了--delete选项时,最好是自己帮自己的忙,执行一个演练操作。

现在轮到介绍前面例子中的选项了。-v(或--verbose)选项,连同--progress,它们命令rsync随时报告它正在进行的操作的细节。在本节前面展示的执行结果中,可以看到rsync告诉你它正在删除什么,以及它正在复制什么。如果是通过自动化的脚本来运行rsync,则不需要使用这个选项,不过,加上也没什么坏处。如果是以命令行交互方式来运行rsync,显示的这些信息则相当有用,因为你能借此明白正在发生的事情。

rsync结果的末尾显示的那些元数据(传输文件的数量和大小及其他有趣的数据),它们之所以出现,是因为在命令中包含了--stats选项。同样,如果在脚本中用rsync,就不需要使用这个选项。但如果是手动运行程序,如果能看到这些信息,确实还是不错的。

-r(或--recursive)选项在其他命令中已经出现多次了,此处它的作用和在其他地方是一样的。加上这个选项后,命令就不会只处理当前目录,它会遍历所有的子目录,处理路径上找到的所有东西。因为想复制整个documents目录及它的所有内容,所以需要使用-r选项。

-t(或--times)选项让rsync在传输文件时保留文件的修改时间。如果没有包含这个选项,rsync就不能判断它以前传输过什么,下一次运行命令时,所有文件会再复制一次。这大概不是你想要的行为,因为它完全背离了rsync的初衷,所以一定要记得包含-t选项。

第7章中讨论的权限,这里又再次出现。-p(或--perms)是告诉rsync要更新目标文件的权限设置,让它们与源文件匹配。这可以让备份文件与源文件尽可能保持一致,所以加上这个选项也是一个不错的想法。当源目录中包含软链接时,-l(或--links)选项就会在目标目录中重建软链接。不必复制实际的文件(这明显不是创建软链接的人的原本意图),只需要复制指向实际文件的链接,这样再一次又保持了源目录的原始状态。

即使具有快速的网络连接,使用-z(或--compress)选项也是个好想法,因为这时rsync将使用gzip来压缩传输的文件。在网速慢的连接中,必须使用这个选项;在快速的连接中,使用这个选项同样也能节省更多的时间。

为了安全,应该使用-e(或--rsh=ssh)选项,告诉rsyncssh对它传输的数据进行加密。文件传输不但容易,而且也安全。应该试一下!

说明 如果使用的是ssh,为什么这里不要求提供密码呢? 因为这里使用的是15.2节中演示的技术,免去了手工输入口令的需要。

最后一个要介绍的选项是--delete。如果你正在创建文件的镜像,显然一定想让镜像与源文件尽可能保持精确。这意味着在源文件中已经被删除的文件,也同样要在目标文件中删除。但这也意味着,你可能意外地删除些原本想保留的东西。如果准备使用--delete选项(估计你会用的),记得一定先用-n(或--dry-run)选项演练一下(在rsync选项介绍的一开始讨论的那个选项)。

rsync命令还有很多其他选项和使用方法(man page列出了8种使用方法,引人入胜)。不过,本节介绍的建立这一命令的方法肯定能够让你开始用这个命令。在显示终端上打开man rsync,可在Google中搜索“rsync tutorial”,都可以找到大量的有用信息。这样想想rsync: 当你正因为误删除了一个文件而大呼“哦,不!”时,马上又想到“哈哈!这个文件原来用rsync备份过了!”。想到这些,你一定会非常乐意花时间学习这个相当丰富而有用的命令吧。

提示 如果想真正保证数据的安全,应该在周期性的cron作业中设置rsync命令自动运行。例如,创建一个名为backup.sh的文件(~/bin是保存这个文件的好地方),在其中输入前面已经用过的命令,如下所示:

  1. $ rsync verbose progress stats
  2. ➥—recursive times perms links
  3. ➥—compress rsh=ssh delete
  4. ➥/home/sam/documents/ will@wordsworth:
  5. ➥/media/backup/documents

用chmod让这个文件成为可执行的:

  1. $ chmod 744 /home/scott/bin/backup.sh

接着将以下几行命令添加到一个名为cronfile的文件中(也可以将这个文件放在~/bin目录中):

  1. # backup documents every morning at 3:05 am
  2. 05 03 * /home/scott/bin/backup.sh

第一行是段注释,解释了这一定时任务的目的,第二行告诉cron在每天夜里的3:05 a.m自动运行/home/scott/bin/backup.sh

现在把这个定时任务加到cron,如下所示:

  1. $ crontab /home/scott/bin/cronfile

现在再也不必为备份文件担心了。它是全自动执行的,只要确保计算机通宵开着就行!

[有关cron的更多信息,可以参阅man cron或文章“Newbie: Intro to cron”(www.unixgeeks.org/security/newbie/unix/cron-1.html)]