同步 UNIX 文件( 二 )


通过与 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 连接,那么会提示您输入远程密码 。如果已经设置了连接,就可以用这种方法执行无人值守的夜间备份 。

推荐阅读